diff --git a/Gopkg.lock b/Gopkg.lock index de192ec683..c3876883e7 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -496,15 +496,15 @@ revision = "4c95b3a336cd95e8c46f80b6f65656c32fd88004" [[projects]] - digest = "1:5f7d166863096a9fb654cedff9e14ea2ec1fe48dc1dd69f7504ef3d87943dc3f" + digest = "1:e23f911287c9b01dd85ad7d21ec1913cb562ff46c06f5b399eb19bd26ae82a2e" name = "github.com/operator-framework/operator-lifecycle-manager" packages = [ "pkg/api/apis/operators", "pkg/api/apis/operators/v1alpha1", ] pruneopts = "NT" - revision = "2abd0e2b4d93b4100220204d429d68a9990a160b" - version = "v3.11.0" + revision = "aeb24aeb363b25c8f9e8267f27579c1483dacc42" + version = "0.9.0" [[projects]] branch = "master" @@ -1170,6 +1170,14 @@ revision = "de19ed4f12d471fccc79f9a9fee73f7c107ecd33" version = "v1.6.0" +[[projects]] + branch = "master" + digest = "1:8ce127d755418ce5f27f1e9178656b7484c5f8794a874c3f9345011dc881852b" + name = "k8s.io/utils" + packages = ["pointer"] + pruneopts = "NT" + revision = "6c36bc71fc4aeb1f49801054e71aebdaef1fbeb4" + [[projects]] digest = "1:c345f7fac6fa77553857d50f04c95a3bf66c1b836b13da426eb533ee1a2ead7d" name = "kubevirt.io/client-go" @@ -1244,6 +1252,18 @@ revision = "c2cacac0af5c2b1ee69845a2bb62ee1c5dc74b84" version = "v0.20.1" +[[projects]] + branch = "release-4.2" + digest = "1:712f726f56166e1641267d47f78119503bd72b189bec0a0fc0cbf5239580b1bc" + name = "kubevirt.io/machine-remediation-operator" + packages = [ + "pkg/apis/machineremediation", + "pkg/apis/machineremediation/v1alpha1", + "pkg/operator/components", + ] + pruneopts = "NT" + revision = "570d094229b1176a979c4784b5cb0ac4f2793288" + [[projects]] digest = "1:06035489efbd51ccface65fc878ceeb849aba05b2f9443c8993f363fc96e80ac" name = "sigs.k8s.io/controller-runtime" @@ -1364,6 +1384,8 @@ "kubevirt.io/kubevirt", "kubevirt.io/kubevirt/pkg/virt-operator/creation/components", "kubevirt.io/kubevirt/pkg/virt-operator/creation/rbac", + "kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1", + "kubevirt.io/machine-remediation-operator/pkg/operator/components", "sigs.k8s.io/controller-runtime/pkg/client", "sigs.k8s.io/controller-runtime/pkg/client/config", "sigs.k8s.io/controller-runtime/pkg/client/fake", diff --git a/Gopkg.toml b/Gopkg.toml index 25e457f93f..f8342e4aab 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -58,6 +58,10 @@ required = [ name = "sigs.k8s.io/controller-tools" version = "=v0.1.8" +[[override]] + name = "kubevirt.io/machine-remediation-operator" + branch = "release-4.2" + [[override]] name = "k8s.io/api" # revision for tag "kubernetes-1.13.1" @@ -94,6 +98,10 @@ required = [ name = "sigs.k8s.io/controller-runtime" version = "=v0.1.10" +[[override]] + name = "github.com/operator-framework/operator-lifecycle-manager" + version = "=0.9.0" + [[constraint]] name = "github.com/operator-framework/operator-sdk" # The version rule is used for a specific release and the master branch for in between releases. @@ -111,4 +119,3 @@ required = [ [[prune.project]] name = "k8s.io/gengo" non-go = false - diff --git a/cluster-up/sync.sh b/cluster-up/sync.sh index 1dec0808b6..3e102efd5b 100755 --- a/cluster-up/sync.sh +++ b/cluster-up/sync.sh @@ -42,4 +42,4 @@ for node in ${nodes[@]}; do done # Deploy the HCO -CMD="./cluster-up/kubectl.sh" ./hack/deploy.sh +CMD="./cluster-up/kubectl.sh" HCO_IMAGE="registry:5000/kubevirt/hyperconverged-cluster-operator:latest" ./hack/deploy.sh diff --git a/cmd/hyperconverged-cluster-operator/main.go b/cmd/hyperconverged-cluster-operator/main.go index 06c341f4dc..caf222eef7 100644 --- a/cmd/hyperconverged-cluster-operator/main.go +++ b/cmd/hyperconverged-cluster-operator/main.go @@ -30,6 +30,7 @@ import ( apiruntime "k8s.io/apimachinery/pkg/runtime" _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" cdiv1alpha1 "kubevirt.io/containerized-data-importer/pkg/apis/core/v1alpha1" + mrv1alpha1 "kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1" logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" ) @@ -120,6 +121,7 @@ func main() { cdiv1alpha1.AddToScheme, networkaddons.AddToScheme, sspopv1.AddToScheme, + mrv1alpha1.AddToScheme, } { if err := f(mgr.GetScheme()); err != nil { log.Error(err, "Failed to add to scheme") diff --git a/deploy/cluster_role.yaml b/deploy/cluster_role.yaml index a010774889..b85f89975e 100644 --- a/deploy/cluster_role.yaml +++ b/deploy/cluster_role.yaml @@ -108,6 +108,13 @@ rules: - get - patch - update +- apiGroups: + - machineremediation.kubevirt.io + resources: + - machineremediationoperators + - machineremediationoperators/status + verbs: + - '*' --- @@ -835,6 +842,51 @@ rules: verbs: - '*' +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + machineremediation.kubevirt.io: "" + machineremediation.kubevirt.io/version: release-4.2 + name: machine-remediation-operator +rules: +- apiGroups: + - machineremediation.kubevirt.io + resources: + - machineremediationoperators + - machineremediationoperators/status + verbs: + - get + - list + - update + - watch +- apiGroups: + - "" + resources: + - serviceaccounts + verbs: + - '*' +- apiGroups: + - apps + resources: + - deployments + verbs: + - '*' +- apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + verbs: + - '*' +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterroles + - clusterrolebindings + verbs: + - '*' + --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole diff --git a/deploy/cluster_role_binding.yaml b/deploy/cluster_role_binding.yaml index a7930973d8..92b3866f5e 100644 --- a/deploy/cluster_role_binding.yaml +++ b/deploy/cluster_role_binding.yaml @@ -117,3 +117,19 @@ subjects: - kind: ServiceAccount name: node-maintenance-operator namespace: kubevirt-hyperconverged +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + machineremediation.kubevirt.io: "" + machineremediation.kubevirt.io/version: release-4.2 + name: machine-remediation-operator +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: machine-remediation-operator +subjects: +- kind: ServiceAccount + name: machine-remediation-operator + namespace: kubevirt-hyperconverged diff --git a/deploy/crds/machine.crd.yaml b/deploy/crds/machine.crd.yaml new file mode 100644 index 0000000000..66c06a1178 --- /dev/null +++ b/deploy/crds/machine.crd.yaml @@ -0,0 +1,196 @@ +--- +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + labels: + controller-tools.k8s.io: "1.0" + name: machines.machine.openshift.io +spec: + additionalPrinterColumns: + - JSONPath: .metadata.annotations['machine\.openshift\.io/instance-state'] + description: State of instance + name: State + type: string + - JSONPath: .metadata.labels['machine\.openshift\.io/instance-type'] + description: Type of instance + name: Type + type: string + - JSONPath: .metadata.labels['machine\.openshift\.io/region'] + description: Region associated with machine + name: Region + type: string + - JSONPath: .metadata.labels['machine\.openshift\.io/zone'] + description: Zone associated with machine + name: Zone + type: string + - JSONPath: .metadata.creationTimestamp + description: Machine age + name: Age + type: date + - JSONPath: .status.nodeRef.name + description: Node associated with machine + name: Node + priority: 1 + type: string + - JSONPath: .spec.providerID + description: Provider ID of machine created in cloud provider + name: ProviderID + priority: 1 + type: string + group: machine.openshift.io + names: + kind: Machine + plural: machines + scope: Namespaced + subresources: + status: {} + validation: + 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/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/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + properties: + metadata: + description: ObjectMeta will autopopulate the Node created. Use this + to indicate what labels, annotations, name prefix, etc., should be + used when creating the Node. + type: object + 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 + providerSpec: + description: ProviderSpec details Provider-specific configuration to + use during node creation. + properties: + value: + description: Value is an inlined, serialized representation of the + resource configuration. It is recommended that providers maintain + their own versioned API types that should be serialized/deserialized + from this field, akin to component config. + type: object + type: object + taints: + description: The list of the taints to be applied to the corresponding + Node in additive manner. This list will not overwrite any other taints + added to the Node on an ongoing basis by other entities. These taints + should be actively reconciled e.g. if you ask the machine controller + to apply a taint and then manually remove the taint the machine controller + will put it back) but not have the machine controller remove any taints + items: + type: object + type: array + required: + - providerSpec + type: object + status: + properties: + addresses: + description: Addresses is a list of addresses assigned to the machine. + Queried from cloud provider, if available. + items: + type: object + type: array + errorMessage: + description: ErrorMessage 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 + errorReason: + description: ErrorReason 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 + lastOperation: + description: LastOperation describes the last-operation performed by + the machine-controller. This API should be useful as a history in + terms of the latest operation performed on the specific machine. It + should also convey the state of the latest-operation for example if + it is still on-going, failed or completed successfully. + properties: + description: + description: Description is the human-readable description of the + last operation. + type: string + lastUpdated: + description: LastUpdated is the timestamp at which LastOperation + API was last-updated. + format: date-time + type: string + state: + description: State is the current status of the last performed operation. + E.g. Processing, Failed, Successful etc + type: string + type: + description: Type is the type of operation which was last performed. + E.g. Create, Delete, Update etc + type: string + type: object + lastUpdated: + description: LastUpdated identifies when this status was last observed. + format: date-time + type: string + nodeRef: + description: NodeRef will point to the corresponding Node if it exists. + type: object + phase: + description: Phase represents the current phase of machine actuation. + E.g. Pending, Running, Terminating, Failed etc. + type: string + providerStatus: + description: ProviderStatus details a Provider-specific status. It is + recommended that providers maintain their own versioned API types + that should be serialized/deserialized from this field. + type: object + type: object + version: v1beta1 +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/deploy/crds/mro.crd.yaml b/deploy/crds/mro.crd.yaml new file mode 100644 index 0000000000..8e0f2b2782 --- /dev/null +++ b/deploy/crds/mro.crd.yaml @@ -0,0 +1,89 @@ + +--- +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + labels: + controller-tools.k8s.io: "1.0" + name: machineremediationoperators.machineremediation.kubevirt.io +spec: + group: machineremediation.kubevirt.io + names: + kind: MachineRemediationOperator + plural: machineremediationoperators + shortNames: + - mro + - mros + scope: Namespaced + subresources: + status: {} + validation: + 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/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/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Specification of MachineRemediationOperator + properties: + imagePullPolicy: + description: The ImagePullPolicy to use. + type: string + imageRegistry: + description: The image registry to pull the container images from Defaults + to the same registry the operator's container image is pulled from. + type: string + type: object + status: + description: Most recently observed status of MachineRemediationOperator + resource + properties: + conditions: + description: type specifies the state of the operator's reconciliation + functionality, which reflects the state of the application + items: + properties: + lastTransitionTime: + description: lastTransitionTime is the time of the last update + to the current status object. + format: date-time + type: string + message: + description: message provides additional information about the + current condition. This is only to be consumed by humans. + type: string + reason: + description: reason is the reason for the condition's last transition. Reasons + are CamelCase + type: string + status: + description: status of the condition, one either True or False. + type: string + type: + description: type specifies the state of the operator's reconciliation + functionality, which reflects the state of the application + type: string + required: + - type + - status + - lastTransitionTime + type: object + type: array + type: object + version: v1alpha1 +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/deploy/deploy.sh b/deploy/deploy.sh index 2b957e353f..d622dfb587 100755 --- a/deploy/deploy.sh +++ b/deploy/deploy.sh @@ -5,6 +5,14 @@ set -x # Create the namespaces for the HCO kubectl create ns kubevirt-hyperconverged +# Create additional namespaces needed for HCO components +namespaces=("openshift" "openshift-machine-api") +for namespace in ${namespaces[@]}; do + if [[ $(kubectl get ns ${namespace}) == "" ]]; then + kubectl create ns ${namespace} + fi +done + # Switch to the HCO namespace. kubectl config set-context $(kubectl config current-context) --namespace=kubevirt-hyperconverged @@ -18,6 +26,7 @@ kubectl create -f https://raw.githubusercontent.com/kubevirt/hyperconverged-clus kubectl create -f https://raw.githubusercontent.com/kubevirt/hyperconverged-cluster-operator/master/deploy/crds/template-validator.crd.yaml kubectl create -f https://raw.githubusercontent.com/kubevirt/hyperconverged-cluster-operator/master/deploy/crds/metrics-aggregation.crd.yaml kubectl create -f https://raw.githubusercontent.com/kubevirt/hyperconverged-cluster-operator/master/deploy/crds/nodemaintenance.crd.yaml +kubectl create -f https://raw.githubusercontent.com/kubevirt/hyperconverged-cluster-operator/master/deploy/crds/mro.crd.yaml # Launch all of the Service Accounts, Cluster Role(Binding)s, and Operators. kubectl create -f https://raw.githubusercontent.com/kubevirt/hyperconverged-cluster-operator/master/deploy/cluster_role.yaml diff --git a/deploy/olm-catalog/kubevirt-hyperconverged/0.0.2/kubevirt-hyperconverged-operator.v0.0.2.clusterserviceversion.yaml b/deploy/olm-catalog/kubevirt-hyperconverged/0.0.2/kubevirt-hyperconverged-operator.v0.0.2.clusterserviceversion.yaml index ae85b7c1b2..e25b9738de 100644 --- a/deploy/olm-catalog/kubevirt-hyperconverged/0.0.2/kubevirt-hyperconverged-operator.v0.0.2.clusterserviceversion.yaml +++ b/deploy/olm-catalog/kubevirt-hyperconverged/0.0.2/kubevirt-hyperconverged-operator.v0.0.2.clusterserviceversion.yaml @@ -62,6 +62,13 @@ metadata: "name": "metrics-aggregation" } }, + { + "apiVersion": "machineremediation.kubevirt.io/v1alpha1", + "kind": "MachineRemediationOperator", + "metadata": { + "name": "mro", + } + }, { "apiVersion": "kubevirt.io/v1alpha1", "kind": "NodeMaintenance", @@ -78,7 +85,7 @@ metadata: categories: OpenShift Optional certified: 'false' containerImage: quay.io/kubevirt/hyperconverged-cluster-operator:latest - createdAt: 2019-08-14 18:20:00.350551627 +0200 CEST m=+0.018187517 + createdAt: 2019-08-15 16:34:10.428354276 +0300 IDT m=+0.036956029 description: Creates and maintains a HyperConverged KubeVirt Deployment repository: https://github.com/kubevirt/hyperconverged-cluster-operator support: 'false' @@ -327,6 +334,13 @@ spec: - get - patch - update + - apiGroups: + - machineremediation.kubevirt.io + resources: + - machineremediationoperators + - machineremediationoperators/status + verbs: + - '*' - serviceAccountName: kubevirt-operator @@ -1036,6 +1050,44 @@ spec: verbs: - '*' + - serviceAccountName: machine-remediation-operator + rules: + - apiGroups: + - machineremediation.kubevirt.io + resources: + - machineremediationoperators + - machineremediationoperators/status + verbs: + - get + - list + - update + - watch + - apiGroups: + - "" + resources: + - serviceaccounts + verbs: + - '*' + - apiGroups: + - apps + resources: + - deployments + verbs: + - '*' + - apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + verbs: + - '*' + - apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterroles + - clusterrolebindings + verbs: + - '*' + - serviceAccountName: kubevirt-ssp-operator rules: - apiGroups: @@ -1409,6 +1461,69 @@ spec: resources: {} serviceAccountName: cluster-network-addons-operator + - name: machine-remediation-operator + spec: + replicas: 1 + selector: + matchLabels: + machineremediation.kubevirt.io: machine-remediation-operator + machineremediation.kubevirt.io/version: release-4.2 + strategy: + type: RollingUpdate + template: + metadata: + labels: + machineremediation.kubevirt.io: machine-remediation-operator + machineremediation.kubevirt.io/version: release-4.2 + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: machineremediation.kubevirt.io + operator: In + values: + - machine-remediation-operator + topologyKey: kubernetes.io/hostname + weight: 50 + containers: + - args: + - --logtostderr=true + - --v=2 + - --namespace=kubevirt-hyperconverged + command: + - /usr/bin/machine-remediation-operator + env: + - name: OPERATOR_VERSION + value: release-4.2 + image: kubevirt/machine-remediation-operator:release-4.2 + imagePullPolicy: IfNotPresent + name: machine-remediation-operator + resources: + requests: + cpu: 10m + memory: 20Mi + nodeSelector: + node-role.kubernetes.io/master: "" + securityContext: + runAsNonRoot: true + serviceAccountName: machine-remediation-operator + tolerations: + - effect: NoSchedule + key: node-role.kubernetes.io/master + - key: CriticalAddonsOnly + operator: Exists + - effect: NoExecute + key: node.kubernetes.io/not-ready + operator: Exists + tolerationSeconds: 120 + - effect: NoExecute + key: node.kubernetes.io/unreachable + operator: Exists + tolerationSeconds: 120 + - name: kubevirt-ssp-operator spec: replicas: 1 @@ -1500,6 +1615,11 @@ spec: kind: NetworkAddonsConfig displayName: Cluster Network Addons description: Cluster Network Addons + - name: machineremediationoperators.machineremediation.kubevirt.io + version: v1alpha1 + kind: MachineRemediationOperator + displayName: Machine Remediation Operator deployment + description: Represents a Machine Remediation Operator deployment - name: kubevirtcommontemplatesbundles.kubevirt.io version: v1 kind: KubevirtCommonTemplatesBundle diff --git a/deploy/olm-catalog/kubevirt-hyperconverged/0.0.2/mro.crd.yaml b/deploy/olm-catalog/kubevirt-hyperconverged/0.0.2/mro.crd.yaml new file mode 100644 index 0000000000..8e0f2b2782 --- /dev/null +++ b/deploy/olm-catalog/kubevirt-hyperconverged/0.0.2/mro.crd.yaml @@ -0,0 +1,89 @@ + +--- +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + labels: + controller-tools.k8s.io: "1.0" + name: machineremediationoperators.machineremediation.kubevirt.io +spec: + group: machineremediation.kubevirt.io + names: + kind: MachineRemediationOperator + plural: machineremediationoperators + shortNames: + - mro + - mros + scope: Namespaced + subresources: + status: {} + validation: + 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/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/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Specification of MachineRemediationOperator + properties: + imagePullPolicy: + description: The ImagePullPolicy to use. + type: string + imageRegistry: + description: The image registry to pull the container images from Defaults + to the same registry the operator's container image is pulled from. + type: string + type: object + status: + description: Most recently observed status of MachineRemediationOperator + resource + properties: + conditions: + description: type specifies the state of the operator's reconciliation + functionality, which reflects the state of the application + items: + properties: + lastTransitionTime: + description: lastTransitionTime is the time of the last update + to the current status object. + format: date-time + type: string + message: + description: message provides additional information about the + current condition. This is only to be consumed by humans. + type: string + reason: + description: reason is the reason for the condition's last transition. Reasons + are CamelCase + type: string + status: + description: status of the condition, one either True or False. + type: string + type: + description: type specifies the state of the operator's reconciliation + functionality, which reflects the state of the application + type: string + required: + - type + - status + - lastTransitionTime + type: object + type: array + type: object + version: v1alpha1 +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/deploy/operator.yaml b/deploy/operator.yaml index 3a2c5840f0..5e7ebee01f 100644 --- a/deploy/operator.yaml +++ b/deploy/operator.yaml @@ -214,6 +214,77 @@ spec: resources: {} serviceAccountName: cluster-network-addons-operator +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + machineremediation.kubevirt.io: machine-remediation-operator + name: machine-remediation-operator + namespace: kubevirt-hyperconverged +spec: + replicas: 1 + selector: + matchLabels: + machineremediation.kubevirt.io: machine-remediation-operator + machineremediation.kubevirt.io/version: release-4.2 + strategy: + type: RollingUpdate + template: + metadata: + creationTimestamp: null + labels: + machineremediation.kubevirt.io: machine-remediation-operator + machineremediation.kubevirt.io/version: release-4.2 + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: machineremediation.kubevirt.io + operator: In + values: + - machine-remediation-operator + topologyKey: kubernetes.io/hostname + weight: 50 + containers: + - args: + - --logtostderr=true + - --v=2 + - --namespace=kubevirt-hyperconverged + command: + - /usr/bin/machine-remediation-operator + env: + - name: OPERATOR_VERSION + value: release-4.2 + image: kubevirt/machine-remediation-operator:release-4.2 + imagePullPolicy: IfNotPresent + name: machine-remediation-operator + resources: + requests: + cpu: 10m + memory: 20Mi + nodeSelector: + node-role.kubernetes.io/master: "" + securityContext: + runAsNonRoot: true + serviceAccountName: machine-remediation-operator + tolerations: + - effect: NoSchedule + key: node-role.kubernetes.io/master + - key: CriticalAddonsOnly + operator: Exists + - effect: NoExecute + key: node.kubernetes.io/not-ready + operator: Exists + tolerationSeconds: 120 + - effect: NoExecute + key: node.kubernetes.io/unreachable + operator: Exists + tolerationSeconds: 120 + --- apiVersion: apps/v1 kind: Deployment diff --git a/deploy/service_account.yaml b/deploy/service_account.yaml index 44b9789901..04c9316638 100644 --- a/deploy/service_account.yaml +++ b/deploy/service_account.yaml @@ -47,3 +47,12 @@ metadata: kubevirt.io: "" name: node-maintenance-operator namespace: kubevirt-hyperconverged +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + machineremediation.kubevirt.io: "" + machineremediation.kubevirt.io/version: release-4.2 + name: machine-remediation-operator + namespace: kubevirt-hyperconverged diff --git a/hack/build-manifests.sh b/hack/build-manifests.sh index 8b038add52..66fdaf360e 100755 --- a/hack/build-manifests.sh +++ b/hack/build-manifests.sh @@ -36,6 +36,9 @@ function versions { NETWORK_ADDONS_TAG="$(dep status -f='{{if eq .ProjectRoot "github.com/kubevirt/cluster-network-addons-operator"}}{{.Version}} {{end}}')" echo "Network Addons: ${NETWORK_ADDONS_TAG}" + MRO_TAG="$(dep status -f='{{if eq .ProjectRoot "kubevirt.io/machine-remediation-operator"}}{{.Version}} {{end}}' | awk '{print $2}')" + echo "MRO: ${MRO_TAG}" + if [ -z "${GITHUB_TOKEN}" ]; then NMO_TAG=$(curl --silent "https://api.github.com/repos/kubevirt/node-maintenance-operator/releases/latest" | grep -Po '"tag_name": "\K.*?(?=")') else @@ -65,7 +68,8 @@ function buildFlags { --cdi-tag=${CDI_TAG} \ --ssp-tag=${SSP_TAG} \ --nmo-tag=${NMO_TAG} \ - --network-addons-tag=${NETWORK_ADDONS_TAG}" + --network-addons-tag=${NETWORK_ADDONS_TAG} \ + --mro-tag=${MRO_TAG}" else BUILD_FLAGS="${BUILD_FLAGS} \ --container-tag=${CONTAINER_TAG}" diff --git a/hack/deploy.sh b/hack/deploy.sh index 563c6a05f0..ec189a58e8 100755 --- a/hack/deploy.sh +++ b/hack/deploy.sh @@ -40,11 +40,19 @@ sed -i "s#image: quay.io/kubevirt/hyperconverged-cluster-operator:latest#image: # create namespaces "${CMD}" create ns kubevirt-hyperconverged +# Create additional namespaces needed for HCO components +namespaces=("openshift" "openshift-machine-api") +for namespace in ${namespaces[@]}; do + if [[ $(${CMD} get ns ${namespace}) == "" ]]; then + ${CMD} create ns ${namespace} + fi +done + if [ "${CMD}" == "oc" ]; then - # Switch project to kubevirt + # Switch project to kubevirt-hyperconverged oc project kubevirt-hyperconverged else - # switch namespace to kubevirt + # switch namespace to kubevirt-hyperconverged ${CMD} config set-context $(${CMD} config current-context) --namespace=kubevirt-hyperconverged fi @@ -59,6 +67,11 @@ function debug(){ exit 1 } +# machine CRD already exists on OKD clusters, so we do not want to deploy it again +if [[ $(${CMD} get crd machines.machine.openshift.io) != "" ]]; then + rm -rf _out/crds/machine.crd.yaml +fi + # Deploy local manifests "${CMD}" create -f _out/cluster_role.yaml "${CMD}" create -f _out/service_account.yaml @@ -71,7 +84,7 @@ sleep 20 "${CMD}" wait deployment/hyperconverged-cluster-operator --for=condition=Available --timeout="360s" || CONTAINER_ERRORED+="${op}" -for op in cdi-operator cluster-network-addons-operator kubevirt-ssp-operator node-maintenance-operator virt-operator; do +for op in cdi-operator cluster-network-addons-operator kubevirt-ssp-operator node-maintenance-operator virt-operator machine-remediation-operator; do "${CMD}" wait deployment/"${op}" --for=condition=Available --timeout="360s" || CONTAINER_ERRORED+="${op} " done @@ -83,6 +96,11 @@ for dep in cdi-apiserver cdi-deployment cdi-uploadproxy virt-api virt-controller "${CMD}" wait deployment/"${dep}" --for=condition=Available --timeout="360s" || CONTAINER_ERRORED+="${dep} " done +# Wait for machine-remediation controllers under the openshift-machine-api namespace +for dep in machine-health-check machine-disruption-budget machine-remediation; do + "${CMD}" -n openshift-machine-api wait deployment/"${dep}" --for=condition=Available --timeout="360s" || CONTAINER_ERRORED+="${dep} " +done + if [ -z "$CONTAINER_ERRORED" ]; then echo "SUCCESS" exit 0 diff --git a/pkg/components/components.go b/pkg/components/components.go index 2a733b6b7b..dc19184168 100644 --- a/pkg/components/components.go +++ b/pkg/components/components.go @@ -261,6 +261,18 @@ func GetClusterRole() *rbacv1.ClusterRole { "update", }, }, + { + APIGroups: []string{ + "machineremediation.kubevirt.io", + }, + Resources: []string{ + "machineremediationoperators", + "machineremediationoperators/status", + }, + Verbs: []string{ + rbacv1.VerbAll, + }, + }, }, } return role diff --git a/pkg/controller/hyperconverged/hyperconverged_controller.go b/pkg/controller/hyperconverged/hyperconverged_controller.go index 77a59fb76d..7be15d76ec 100644 --- a/pkg/controller/hyperconverged/hyperconverged_controller.go +++ b/pkg/controller/hyperconverged/hyperconverged_controller.go @@ -29,6 +29,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" kubevirtv1 "kubevirt.io/client-go/api/v1" cdiv1alpha1 "kubevirt.io/containerized-data-importer/pkg/apis/core/v1alpha1" + mrv1alpha1 "kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1" logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" ) @@ -89,6 +90,7 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error { &sspv1.KubevirtNodeLabellerBundle{}, &sspv1.KubevirtTemplateValidator{}, &sspv1.KubevirtMetricsAggregation{}, + &mrv1alpha1.MachineRemediationOperator{}, } { err = c.Watch(&source.Kind{Type: resource}, &handler.EnqueueRequestForOwner{ IsController: true, @@ -192,6 +194,7 @@ func (r *ReconcileHyperConverged) Reconcile(request reconcile.Request) (reconcil r.ensureKubeVirtNodeLabellerBundle, r.ensureKubeVirtTemplateValidator, r.ensureKubeVirtMetricsAggregation, + r.ensureMachineRemediationOperator, } { err = f(instance, reqLogger, request) if err != nil { @@ -866,6 +869,119 @@ func (r *ReconcileHyperConverged) ensureKubeVirtMetricsAggregation(instance *hco return r.client.Status().Update(context.TODO(), instance) } +// newMROForCR returns a MachineRemediationOperator CR +func newMachineRemediationOperatorForCR(cr *hcov1alpha1.HyperConverged, namespace string) *mrv1alpha1.MachineRemediationOperator { + labels := map[string]string{ + "app": cr.Name, + } + return &mrv1alpha1.MachineRemediationOperator{ + ObjectMeta: metav1.ObjectMeta{ + Name: "mro-" + cr.Name, + Labels: labels, + Namespace: namespace, + }, + } +} + +func (r *ReconcileHyperConverged) ensureMachineRemediationOperator(instance *hcov1alpha1.HyperConverged, logger logr.Logger, request reconcile.Request) error { + mro := newMachineRemediationOperatorForCR(instance, request.Namespace) + if err := controllerutil.SetControllerReference(instance, mro, r.scheme); err != nil { + return err + } + + key, err := client.ObjectKeyFromObject(mro) + if err != nil { + logger.Error(err, "Failed to get object key for MachineRemediationOperator") + } + + found := &mrv1alpha1.MachineRemediationOperator{} + err = r.client.Get(context.TODO(), key, found) + if err != nil && errors.IsNotFound(err) { + logger.Info("Creating MachineRemediationOperator") + return r.client.Create(context.TODO(), mro) + } + + if err != nil { + return err + } + + logger.Info("MachineRemediationOperator already exists", "MachineRemediationOperator.Namespace", found.Namespace, "MachineRemediationOperator.Name", found.Name) + + // Add it to the list of RelatedObjects if found + objectRef, err := reference.GetReference(r.scheme, found) + if err != nil { + return err + } + objectreferencesv1.SetObjectReference(&instance.Status.RelatedObjects, *objectRef) + + // Handle MachineRemediationOperator resource conditions + if found.Status.Conditions == nil { + logger.Info("MachineRemediationOperator resource is not reporting Conditions on it's Status") + conditionsv1.SetStatusCondition(&r.conditions, conditionsv1.Condition{ + Type: conditionsv1.ConditionAvailable, + Status: corev1.ConditionFalse, + Reason: "MachineRemediationOperatorConditions", + Message: "MachineRemediationOperator resource has no conditions", + }) + conditionsv1.SetStatusCondition(&r.conditions, conditionsv1.Condition{ + Type: conditionsv1.ConditionProgressing, + Status: corev1.ConditionTrue, + Reason: "MachineRemediationOperatorConditions", + Message: "MachineRemediationOperator resource has no conditions", + }) + conditionsv1.SetStatusCondition(&r.conditions, conditionsv1.Condition{ + Type: conditionsv1.ConditionUpgradeable, + Status: corev1.ConditionFalse, + Reason: "MachineRemediationOperatorConditions", + Message: "MachineRemediationOperator resource has no conditions", + }) + } else { + for _, condition := range found.Status.Conditions { + // convert the KubeVirt condition type to one we understand + switch conditionsv1.ConditionType(condition.Type) { + case conditionsv1.ConditionAvailable: + if condition.Status == corev1.ConditionFalse { + logger.Info("MachineRemediationOperator is not 'Available'") + conditionsv1.SetStatusCondition(&r.conditions, conditionsv1.Condition{ + Type: conditionsv1.ConditionAvailable, + Status: corev1.ConditionFalse, + Reason: "MachineRemediationOperatorNotAvailable", + Message: fmt.Sprintf("MachineRemediationOperator is not available: %v", string(condition.Message)), + }) + } + case conditionsv1.ConditionProgressing: + if condition.Status == corev1.ConditionTrue { + logger.Info("MachineRemediationOperator is 'Progressing'") + conditionsv1.SetStatusCondition(&r.conditions, conditionsv1.Condition{ + Type: conditionsv1.ConditionProgressing, + Status: corev1.ConditionTrue, + Reason: "MachineRemediationOperatorProgressing", + Message: fmt.Sprintf("MachineRemediationOperator is progressing: %v", string(condition.Message)), + }) + conditionsv1.SetStatusCondition(&r.conditions, conditionsv1.Condition{ + Type: conditionsv1.ConditionUpgradeable, + Status: corev1.ConditionFalse, + Reason: "MachineRemediationOperatorProgressing", + Message: fmt.Sprintf("MachineRemediationOperator is progressing: %v", string(condition.Message)), + }) + } + case conditionsv1.ConditionDegraded: + if condition.Status == corev1.ConditionTrue { + logger.Info("MachineRemediationOperator is 'Degraded'") + conditionsv1.SetStatusCondition(&r.conditions, conditionsv1.Condition{ + Type: conditionsv1.ConditionDegraded, + Status: corev1.ConditionTrue, + Reason: "MachineRemediationOperatorDegraded", + Message: fmt.Sprintf("MachineRemediationOperator is degraded: %v", string(condition.Message)), + }) + } + } + } + } + + return r.client.Status().Update(context.TODO(), instance) +} + // The set of resources managed by the HCO func (r *ReconcileHyperConverged) getAllResources(cr *hcov1alpha1.HyperConverged, request reconcile.Request) []runtime.Object { return []runtime.Object{ @@ -876,6 +992,7 @@ func (r *ReconcileHyperConverged) getAllResources(cr *hcov1alpha1.HyperConverged newKubeVirtCommonTemplateBundleForCR(cr, OpenshiftNamespace), newKubeVirtNodeLabellerBundleForCR(cr, request.Namespace), newKubeVirtTemplateValidatorForCR(cr, request.Namespace), + newMachineRemediationOperatorForCR(cr, request.Namespace), } } diff --git a/pkg/controller/hyperconverged/hyperconverged_controller_test.go b/pkg/controller/hyperconverged/hyperconverged_controller_test.go index 3e4eef592f..b57f458a7f 100644 --- a/pkg/controller/hyperconverged/hyperconverged_controller_test.go +++ b/pkg/controller/hyperconverged/hyperconverged_controller_test.go @@ -28,6 +28,7 @@ import ( hcov1alpha1 "github.com/kubevirt/hyperconverged-cluster-operator/pkg/apis/hco/v1alpha1" kubevirt "kubevirt.io/client-go/api/v1" cdi "kubevirt.io/containerized-data-importer/pkg/apis/core/v1alpha1" + mrv1alpha1 "kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1" ) const ( @@ -48,6 +49,7 @@ func init() { networkaddons.SchemeBuilder.AddToScheme(scheme.Scheme) cdi.AddToScheme(scheme.Scheme) kubevirt.AddToScheme(scheme.Scheme) + mrv1alpha1.AddToScheme(scheme.Scheme) } var _ = Describe("HyperconvergedController", func() { @@ -117,6 +119,13 @@ var _ = Describe("HyperconvergedController", func() { }) }) + Context("MachineRemediationCR CR", func() { + It("should have metadata", func() { + cr := newMachineRemediationOperatorForCR(instance, namespace) + checkMetadata(cr.ObjectMeta, "mro-"+instance.Name, appLabel, namespace) + }) + }) + }) Describe("Deploying HCO", func() { Context("HCO Lifecycle", func() { diff --git a/templates/cluster_role.yaml.in b/templates/cluster_role.yaml.in index f2c1381671..138fac382a 100644 --- a/templates/cluster_role.yaml.in +++ b/templates/cluster_role.yaml.in @@ -3,6 +3,7 @@ {{.KubeVirt.ClusterRoleString}} {{.CDI.ClusterRoleString}} {{.CNA.ClusterRoleString}} +{{.MRO.ClusterRoleString}} --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole diff --git a/templates/cluster_role_binding.yaml.in b/templates/cluster_role_binding.yaml.in index 80ba8d73f6..f89e1b9bf6 100644 --- a/templates/cluster_role_binding.yaml.in +++ b/templates/cluster_role_binding.yaml.in @@ -117,4 +117,20 @@ subjects: - kind: ServiceAccount name: node-maintenance-operator namespace: {{.Namespace}} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + machineremediation.kubevirt.io: "" + machineremediation.kubevirt.io/version: {{.MRO.OperatorTag}} + name: machine-remediation-operator +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: machine-remediation-operator +subjects: +- kind: ServiceAccount + name: machine-remediation-operator + namespace: {{.Namespace}} {{end}} diff --git a/templates/crds/mro.crd.yaml.in b/templates/crds/mro.crd.yaml.in new file mode 100644 index 0000000000..89024f2274 --- /dev/null +++ b/templates/crds/mro.crd.yaml.in @@ -0,0 +1,90 @@ +{{if .Converged}} +--- +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + labels: + controller-tools.k8s.io: "1.0" + name: machineremediationoperators.machineremediation.kubevirt.io +spec: + group: machineremediation.kubevirt.io + names: + kind: MachineRemediationOperator + plural: machineremediationoperators + shortNames: + - mro + - mros + scope: Namespaced + subresources: + status: {} + validation: + 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/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/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Specification of MachineRemediationOperator + properties: + imagePullPolicy: + description: The ImagePullPolicy to use. + type: string + imageRegistry: + description: The image registry to pull the container images from Defaults + to the same registry the operator's container image is pulled from. + type: string + type: object + status: + description: Most recently observed status of MachineRemediationOperator + resource + properties: + conditions: + description: type specifies the state of the operator's reconciliation + functionality, which reflects the state of the application + items: + properties: + lastTransitionTime: + description: lastTransitionTime is the time of the last update + to the current status object. + format: date-time + type: string + message: + description: message provides additional information about the + current condition. This is only to be consumed by humans. + type: string + reason: + description: reason is the reason for the condition's last transition. Reasons + are CamelCase + type: string + status: + description: status of the condition, one either True or False. + type: string + type: + description: type specifies the state of the operator's reconciliation + functionality, which reflects the state of the application + type: string + required: + - type + - status + - lastTransitionTime + type: object + type: array + type: object + version: v1alpha1 +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +{{end}} \ No newline at end of file diff --git a/templates/olm-catalog/kubevirt-hyperconverged/VERSION/kubevirt-hyperconverged-operator.VERSION.clusterserviceversion.yaml.in b/templates/olm-catalog/kubevirt-hyperconverged/VERSION/kubevirt-hyperconverged-operator.VERSION.clusterserviceversion.yaml.in index 058bb825a3..4ef45502e0 100644 --- a/templates/olm-catalog/kubevirt-hyperconverged/VERSION/kubevirt-hyperconverged-operator.VERSION.clusterserviceversion.yaml.in +++ b/templates/olm-catalog/kubevirt-hyperconverged/VERSION/kubevirt-hyperconverged-operator.VERSION.clusterserviceversion.yaml.in @@ -62,6 +62,13 @@ metadata: "name": "metrics-aggregation" } }, + { + "apiVersion": "machineremediation.kubevirt.io/v1alpha1", + "kind": "MachineRemediationOperator", + "metadata": { + "name": "mro", + } + }, { "apiVersion": "kubevirt.io/v1alpha1", "kind": "NodeMaintenance", @@ -210,6 +217,9 @@ spec: - serviceAccountName: cluster-network-addons-operator rules: {{.CNA.ClusterRules}} + - serviceAccountName: machine-remediation-operator + rules: +{{.MRO.Rules}} - serviceAccountName: kubevirt-ssp-operator rules: - apiGroups: @@ -406,6 +416,9 @@ spec: - name: cluster-network-addons-operator spec: {{.CNA.DeploymentSpec}} + - name: machine-remediation-operator + spec: +{{.MRO.DeploymentSpec}} - name: kubevirt-ssp-operator spec: replicas: 1 @@ -499,6 +512,11 @@ spec: kind: {{.CNA.CRD.Spec.Names.Kind}} displayName: Cluster Network Addons description: Cluster Network Addons + - name: machineremediationoperators.machineremediation.kubevirt.io + version: v1alpha1 + kind: MachineRemediationOperator + displayName: Machine Remediation Operator deployment + description: Represents a Machine Remediation Operator deployment - name: kubevirtcommontemplatesbundles.kubevirt.io version: v1 kind: KubevirtCommonTemplatesBundle diff --git a/templates/operator.yaml.in b/templates/operator.yaml.in index 29054beb1d..6b25d237e4 100644 --- a/templates/operator.yaml.in +++ b/templates/operator.yaml.in @@ -3,6 +3,7 @@ {{.KubeVirt.Deployment}} {{.CDI.Deployment}} {{.CNA.Deployment}} +{{.MRO.Deployment}} --- apiVersion: apps/v1 kind: Deployment diff --git a/templates/service_account.yaml.in b/templates/service_account.yaml.in index d6d30f8b47..47955d1503 100644 --- a/templates/service_account.yaml.in +++ b/templates/service_account.yaml.in @@ -47,4 +47,13 @@ metadata: kubevirt.io: "" name: node-maintenance-operator namespace: {{.Namespace}} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + machineremediation.kubevirt.io: "" + machineremediation.kubevirt.io/version: {{.MRO.OperatorTag}} + name: machine-remediation-operator + namespace: {{.Namespace}} {{end}} diff --git a/tools/manifest-templator/manifest-templator.go b/tools/manifest-templator/manifest-templator.go index 1e9c5eb705..7591a5d46e 100644 --- a/tools/manifest-templator/manifest-templator.go +++ b/tools/manifest-templator/manifest-templator.go @@ -31,7 +31,7 @@ import ( "github.com/ghodss/yaml" "github.com/spf13/pflag" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" cnacomponents "github.com/kubevirt/cluster-network-addons-operator/pkg/components" @@ -40,6 +40,7 @@ import ( cdicomponents "kubevirt.io/containerized-data-importer/pkg/operator/resources/operator" kvcomponents "kubevirt.io/kubevirt/pkg/virt-operator/creation/components" kvrbac "kubevirt.io/kubevirt/pkg/virt-operator/creation/rbac" + mrocomponents "kubevirt.io/machine-remediation-operator/pkg/operator/components" ) type operatorData struct { @@ -72,6 +73,7 @@ type templateData struct { CNA *operatorData SSP *operatorData NMO *operatorData + MRO *operatorData } func check(err error) { @@ -375,6 +377,54 @@ func getCNA(data *templateData) { data.CNA.CRDString = crdString } +func getMRO(data *templateData) { + // create MRO operator deployment + deployWriter := strings.Builder{} + deployData := &mrocomponents.DeploymentData{ + Name: "machine-remediation-operator", + Namespace: data.Namespace, + ImageRepository: data.ContainerPrefix, + PullPolicy: v1.PullIfNotPresent, + Verbosity: "2", + OperatorVersion: data.MRO.OperatorTag, + } + deploy := mrocomponents.NewDeployment(deployData) + + err := marshallObject(deploy, &deployWriter) + check(err) + deployString := deployWriter.String() + + // Get MRO DeploymentSpec for CSV + deploySpecWriter := strings.Builder{} + err = marshallObject(deploy.Spec, &deploySpecWriter) + check(err) + deploySpecString := fixResourceString(deploySpecWriter.String(), 12) + + // Get MRO ClusterRole + clusterRoleWriter := strings.Builder{} + clusterRole := mrocomponents.NewClusterRole( + "machine-remediation-operator", + mrocomponents.Rules["machine-remediation-operator"], + data.MRO.OperatorTag, + ) + err = marshallObject(clusterRole, &clusterRoleWriter) + check(err) + clusterRoleString := clusterRoleWriter.String() + + // Get the Rules out of MRO ClusterRole + rulesWriter := strings.Builder{} + for _, rule := range mrocomponents.Rules["machine-remediation-operator"] { + err := marshallObject(rule, &rulesWriter) + check(err) + } + rulesString := fixResourceString(rulesWriter.String(), 14) + + data.MRO.Deployment = deployString + data.MRO.DeploymentSpec = deploySpecString + data.MRO.ClusterRoleString = clusterRoleString + data.MRO.Rules = rulesString +} + func main() { converged := flag.Bool("converged", false, "") namespace := flag.String("namespace", "kubevirt-hyperconverged", "") @@ -392,6 +442,7 @@ func main() { sspTag := flag.String("ssp-tag", *containerTag, "") nmoTag := flag.String("nmo-tag", *containerTag, "") networkAddonsTag := flag.String("network-addons-tag", *containerTag, "") + mroTag := flag.String("mro-tag", *containerTag, "") pflag.CommandLine.AddGoFlagSet(flag.CommandLine) pflag.CommandLine.ParseErrorsWhitelist.UnknownFlags = true @@ -402,7 +453,7 @@ func main() { Replaces = false } - data := templateData{ + data := &templateData{ Converged: *converged, Namespace: *namespace, CsvVersion: *csvVersion, @@ -418,17 +469,20 @@ func main() { CNA: &operatorData{OperatorTag: *networkAddonsTag, ComponentTag: *networkAddonsTag}, SSP: &operatorData{OperatorTag: *sspTag, ComponentTag: *sspTag}, NMO: &operatorData{OperatorTag: *nmoTag, ComponentTag: *nmoTag}, + MRO: &operatorData{OperatorTag: *mroTag, ComponentTag: *mroTag}, } data.CreatedAt = time.Now().String() // Load in all HCO Resources - getHCO(&data) + getHCO(data) // Load in all of the KubeVirt Resources - getKubeVirt(&data) + getKubeVirt(data) // Load in all CDI Resources - getCDI(&data) + getCDI(data) // Load in all CNA Resources - getCNA(&data) + getCNA(data) + // Load in all MRO resources + getMRO(data) if *inputFile == "" { panic("Must specify input file") diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/cmd/catalog/main.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/cmd/catalog/main.go index 6160ce9786..0e456295e1 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/cmd/catalog/main.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/cmd/catalog/main.go @@ -8,16 +8,25 @@ import ( "strings" "time" + configv1client "github.com/openshift/client-go/config/clientset/versioned/typed/config/v1" + "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient" + "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorstatus" + "github.com/prometheus/client_golang/prometheus/promhttp" log "github.com/sirupsen/logrus" + v1 "k8s.io/api/core/v1" + "k8s.io/client-go/tools/clientcmd" "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/catalog" "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/signals" + "github.com/operator-framework/operator-lifecycle-manager/pkg/metrics" olmversion "github.com/operator-framework/operator-lifecycle-manager/pkg/version" ) const ( - defaultWakeupInterval = 15 * time.Minute - defaultCatalogNamespace = "tectonic-system" + defaultWakeupInterval = 15 * time.Minute + defaultCatalogNamespace = "openshift-operator-lifecycle-manager" + defaultConfigMapServerImage = "quay.io/operatorframework/configmap-operator-registry:latest" + defaultOperatorName = "" ) // config flags defined globally so that they appear on the test binary as well @@ -34,12 +43,28 @@ var ( catalogNamespace = flag.String( "namespace", defaultCatalogNamespace, "namespace where catalog will run and install catalog resources") + configmapServerImage = flag.String( + "configmapServerImage", defaultConfigMapServerImage, "the image to use for serving the operator registry api for a configmap") + + writeStatusName = flag.String( + "writeStatusName", defaultOperatorName, "ClusterOperator name in which to write status, set to \"\" to disable.") + debug = flag.Bool( "debug", false, "use debug log level") version = flag.Bool("version", false, "displays olm version") + + tlsKeyPath = flag.String( + "tls-key", "", "Path to use for private key (requires tls-cert)") + + tlsCertPath = flag.String( + "tls-cert", "", "Path to use for certificate key (requires tls-key)") ) +func init() { + metrics.RegisterCatalog() +} + func main() { stopCh := signals.SetupSignalHandler() @@ -54,8 +79,29 @@ func main() { os.Exit(0) } + // `namespaces` will always contain at least one entry: if `*watchedNamespaces` is + // the empty string, the resulting array will be `[]string{""}`. + namespaces := strings.Split(*watchedNamespaces, ",") + for _, ns := range namespaces { + if ns == v1.NamespaceAll { + namespaces = []string{v1.NamespaceAll} + break + } + } + + logger := log.New() if *debug { - log.SetLevel(log.DebugLevel) + logger.SetLevel(log.DebugLevel) + } + logger.Infof("log level %s", logger.Level) + + var useTLS bool + if *tlsCertPath != "" && *tlsKeyPath == "" || *tlsCertPath == "" && *tlsKeyPath != "" { + logger.Warn("both --tls-key and --tls-crt must be provided for TLS to be enabled, falling back to non-https") + } else if *tlsCertPath == "" && *tlsKeyPath == "" { + logger.Info("TLS keys not set, using non-https") + } else { + useTLS = true } // Serve a health check. @@ -64,11 +110,36 @@ func main() { }) go http.ListenAndServe(":8080", nil) + http.Handle("/metrics", promhttp.Handler()) + if useTLS { + go http.ListenAndServeTLS(":8081", *tlsCertPath, *tlsKeyPath, nil) + } else { + go http.ListenAndServe(":8081", nil) + } + + // create a config client for operator status + config, err := clientcmd.BuildConfigFromFlags("", *kubeConfigPath) + if err != nil { + log.Fatalf("error configuring client: %s", err.Error()) + } + configClient, err := configv1client.NewForConfig(config) + if err != nil { + log.Fatalf("error configuring client: %s", err.Error()) + } + opClient := operatorclient.NewClientFromConfig(*kubeConfigPath, logger) + // Create a new instance of the operator. - catalogOperator, err := catalog.NewOperator(*kubeConfigPath, *wakeupInterval, *catalogNamespace, strings.Split(*watchedNamespaces, ",")...) + catalogOperator, err := catalog.NewOperator(*kubeConfigPath, logger, *wakeupInterval, *configmapServerImage, *catalogNamespace, namespaces...) if err != nil { log.Panicf("error configuring operator: %s", err.Error()) } - catalogOperator.Run(stopCh) + ready, done, sync := catalogOperator.Run(stopCh) + <-ready + + if *writeStatusName != "" { + operatorstatus.MonitorClusterStatus(*writeStatusName, sync, stopCh, opClient, configClient) + } + + <-done } diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/cmd/olm/main.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/cmd/olm/main.go index 0577d99e0d..610f7e2c17 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/cmd/olm/main.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/cmd/olm/main.go @@ -8,33 +8,27 @@ import ( "strings" "time" + configv1client "github.com/openshift/client-go/config/clientset/versioned/typed/config/v1" + "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorstatus" + "github.com/prometheus/client_golang/prometheus/promhttp" log "github.com/sirupsen/logrus" + v1 "k8s.io/api/core/v1" + "k8s.io/client-go/tools/clientcmd" "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client" "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install" "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/olm" "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient" "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/signals" + "github.com/operator-framework/operator-lifecycle-manager/pkg/metrics" olmversion "github.com/operator-framework/operator-lifecycle-manager/pkg/version" ) const ( - envOperatorName = "OPERATOR_NAME" - envOperatorNamespace = "OPERATOR_NAMESPACE" - ALMManagedAnnotationKey = "alm-manager" - defaultWakeupInterval = 5 * time.Minute + defaultOperatorName = "" ) -// helper function for required env vars -func envOrDie(varname, description string) string { - val := os.Getenv(varname) - if len(val) == 0 { - log.Fatalf("must set env %s - %s", varname, description) - } - return val -} - // config flags defined globally so that they appear on the test binary as well var ( kubeConfigPath = flag.String( @@ -44,17 +38,30 @@ var ( "interval", defaultWakeupInterval, "wake up interval") watchedNamespaces = flag.String( - "watchedNamespaces", "", "comma separated list of namespaces for alm operator to watch. "+ + "watchedNamespaces", "", "comma separated list of namespaces for olm operator to watch. "+ "If not set, or set to the empty string (e.g. `-watchedNamespaces=\"\"`), "+ - "alm operator will watch all namespaces in the cluster.") + "olm operator will watch all namespaces in the cluster.") + + writeStatusName = flag.String( + "writeStatusName", defaultOperatorName, "ClusterOperator name in which to write status, set to \"\" to disable.") debug = flag.Bool( "debug", false, "use debug log level") version = flag.Bool("version", false, "displays olm version") + + tlsKeyPath = flag.String( + "tls-key", "", "Path to use for private key (requires tls-cert)") + + tlsCertPath = flag.String( + "tls-cert", "", "Path to use for certificate key (requires tls-key)") ) -// main function - entrypoint to ALM operator +func init() { + metrics.RegisterOLM() +} + +// main function - entrypoint to OLM operator func main() { stopCh := signals.SetupSignalHandler() @@ -69,41 +76,57 @@ func main() { os.Exit(0) } - // Env Vars - operatorNamespace := envOrDie( - envOperatorNamespace, "used to set annotation indicating which ALM operator manages a namespace") - - operatorName := envOrDie( - envOperatorName, "used to distinguish ALM operators of the same name") + // `namespaces` will always contain at least one entry: if `*watchedNamespaces` is + // the empty string, the resulting array will be `[]string{""}`. + namespaces := strings.Split(*watchedNamespaces, ",") + for _, ns := range namespaces { + if ns == v1.NamespaceAll { + namespaces = []string{v1.NamespaceAll} + break + } + } - annotation := map[string]string{ - ALMManagedAnnotationKey: fmt.Sprintf("%s.%s", operatorNamespace, operatorName), + // Create a client for OLM + crClient, err := client.NewClient(*kubeConfigPath) + if err != nil { + log.Fatalf("error configuring client: %s", err.Error()) } + logger := log.New() + // Set log level to debug if `debug` flag set if *debug { - log.SetLevel(log.DebugLevel) + logger.SetLevel(log.DebugLevel) } + logger.Infof("log level %s", logger.Level) - // `namespaces` will always contain at least one entry: if `*watchedNamespaces` is - // the empty string, the resulting array will be `[]string{""}`. - namespaces := strings.Split(*watchedNamespaces, ",") + opClient := operatorclient.NewClientFromConfig(*kubeConfigPath, logger) - // Create a client for OLM - crClient, err := client.NewClient(*kubeConfigPath) + // create a config client for operator status + config, err := clientcmd.BuildConfigFromFlags("", *kubeConfigPath) + if err != nil { + log.Fatalf("error configuring client: %s", err.Error()) + } + configClient, err := configv1client.NewForConfig(config) if err != nil { log.Fatalf("error configuring client: %s", err.Error()) } - - opClient := operatorclient.NewClientFromConfig(*kubeConfigPath) // Create a new instance of the operator. - operator, err := olm.NewOperator(crClient, opClient, &install.StrategyResolver{}, *wakeupInterval, annotation, namespaces) + operator, err := olm.NewOperator(logger, crClient, opClient, &install.StrategyResolver{}, *wakeupInterval, namespaces) if err != nil { log.Fatalf("error configuring operator: %s", err.Error()) } - defer operator.Cleanup() + + var useTLS bool + if *tlsCertPath != "" && *tlsKeyPath == "" || *tlsCertPath == "" && *tlsKeyPath != "" { + logger.Warn("both --tls-key and --tls-crt must be provided for TLS to be enabled, falling back to non-https") + } else if *tlsCertPath == "" && *tlsKeyPath == "" { + logger.Info("TLS keys not set, using non-https") + } else { + useTLS = true + } // Serve a health check. http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) { @@ -111,5 +134,19 @@ func main() { }) go http.ListenAndServe(":8080", nil) - operator.Run(stopCh) + http.Handle("/metrics", promhttp.Handler()) + if useTLS { + go http.ListenAndServeTLS(":8081", *tlsCertPath, *tlsKeyPath, nil) + } else { + go http.ListenAndServe(":8081", nil) + } + + ready, done, sync := operator.Run(stopCh) + <-ready + + if *writeStatusName != "" { + operatorstatus.MonitorClusterStatus(*writeStatusName, sync, stopCh, opClient, configClient) + } + + <-done } diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/cmd/package-server/main.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/cmd/package-server/main.go index cd1a7e225b..4ab3a5926c 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/cmd/package-server/main.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/cmd/package-server/main.go @@ -36,8 +36,8 @@ var ( func init() { flags := cmd.Flags() - // flags.BoolVar(&options.InsecureKubeletTLS, "kubelet-insecure-tls", options.InsecureKubeletTLS, "Do not verify CA of serving certificates presented by Kubelets. For testing purposes only.") flags.DurationVar(&options.WakeupInterval, "interval", options.WakeupInterval, "Interval at which to re-sync CatalogSources") + flags.StringVar(&options.GlobalNamespace, "global-namespace", options.GlobalNamespace, "Name of the namespace where the global CatalogSources are located") flags.StringSliceVar(&options.WatchedNamespaces, "watched-namespaces", options.WatchedNamespaces, "List of namespaces the package-server will watch watch for CatalogSources") flags.StringVar(&options.Kubeconfig, "kubeconfig", options.Kubeconfig, "The path to the kubeconfig used to connect to the Kubernetes API server and the Kubelets (defaults to in-cluster config)") flags.BoolVar(&options.Debug, "debug", options.Debug, "use debug log level") diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/cmd/validator/main.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/cmd/validator/main.go deleted file mode 100644 index 06827d4637..0000000000 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/cmd/validator/main.go +++ /dev/null @@ -1,32 +0,0 @@ -package main - -import ( - "fmt" - "log" - "os" - "path/filepath" - - "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/schema" -) - -func main() { - manifestDir := os.Args[1] - - err := schema.CheckCatalogResources(manifestDir) - if err != nil { - log.Fatal(err) - } - - filepath.Walk(manifestDir, func(path string, f os.FileInfo, err error) error { - if path == manifestDir || !f.IsDir() { - return nil - } - - fmt.Printf("Validating upgrade path for %s in %s\n", f.Name(), path) - err = schema.CheckUpgradePath(path) - if err != nil { - log.Fatal(err) - } - return nil - }) -} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/deploy/ocp/manifests/latest b/vendor/github.com/operator-framework/operator-lifecycle-manager/deploy/ocp/manifests/latest new file mode 120000 index 0000000000..52090fdd35 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/deploy/ocp/manifests/latest @@ -0,0 +1 @@ +./0.9.0 \ No newline at end of file diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/deploy/okd/manifests/latest b/vendor/github.com/operator-framework/operator-lifecycle-manager/deploy/okd/manifests/latest new file mode 120000 index 0000000000..52090fdd35 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/deploy/okd/manifests/latest @@ -0,0 +1 @@ +./0.9.0 \ No newline at end of file diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/deploy/upstream/manifests/latest b/vendor/github.com/operator-framework/operator-lifecycle-manager/deploy/upstream/manifests/latest new file mode 120000 index 0000000000..52090fdd35 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/deploy/upstream/manifests/latest @@ -0,0 +1 @@ +./0.9.0 \ No newline at end of file diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1/doc.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1/doc.go new file mode 100644 index 0000000000..fed7ecd277 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1/doc.go @@ -0,0 +1,3 @@ +// +k8s:deepcopy-gen=package +// +groupName=operators.coreos.com +package v1 diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1/operatorgroup_types.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1/operatorgroup_types.go new file mode 100644 index 0000000000..838b5222a1 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1/operatorgroup_types.go @@ -0,0 +1,68 @@ +package v1 + +import ( + "sort" + "strings" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + OperatorGroupAnnotationKey = "olm.operatorGroup" + OperatorGroupNamespaceAnnotationKey = "olm.operatorNamespace" + OperatorGroupTargetsAnnotationKey = "olm.targetNamespaces" + OperatorGroupProvidedAPIsAnnotationKey = "olm.providedAPIs" +) + +type OperatorGroupSpec struct { + // Selector selects the OperatorGroup's target namespaces. + // +optional + Selector *metav1.LabelSelector `json:"selector,omitempty"` + + // TargetNamespaces is an explicit set of namespaces to target. + // If it is set, Selector is ignored. + // +optional + TargetNamespaces []string `json:"targetNamespaces,omitempty"` + + // ServiceAccount to bind OperatorGroup roles to. + ServiceAccount corev1.ServiceAccount `json:"serviceAccount,omitempty"` + + // Static tells OLM not to update the OperatorGroup's providedAPIs annotation + // +optional + StaticProvidedAPIs bool `json:"staticProvidedAPIs,omitempty"` +} + +type OperatorGroupStatus struct { + // Namespaces is the set of target namespaces for the OperatorGroup. + Namespaces []string `json:"namespaces,omitempty"` + + // ProvidedAPIs represents the set of APIs provided by the OperatorGroup's member CSVs. + // ProvidedAPIs []metav1.TypeMeta `json:"providedAPIs,omitempty"` + + // LastUpdated is a timestamp of the last time the OperatorGroup's status was Updated. + LastUpdated metav1.Time `json:"lastUpdated"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +genclient +type OperatorGroup struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata"` + + Spec OperatorGroupSpec `json:"spec"` + Status OperatorGroupStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type OperatorGroupList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []OperatorGroup `json:"items"` +} + +func (o *OperatorGroup) BuildTargetNamespaces() string { + sort.Strings(o.Status.Namespaces) + return strings.Join(o.Status.Namespaces, ",") +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1/register.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1/register.go new file mode 100644 index 0000000000..21dff3b8a3 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1/register.go @@ -0,0 +1,50 @@ +package v1 + +import ( + "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + k8sscheme "k8s.io/client-go/kubernetes/scheme" + + "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators" +) + +const ( + GroupName = "operators.coreos.com" + GroupVersion = "v1" +) + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: operators.GroupName, Version: GroupVersion} + +// 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 + serScheme = runtime.NewScheme() +) + +func init() { + k8sscheme.AddToScheme(serScheme) + scheme.AddToScheme(serScheme) +} + +// Adds the list of known types to Scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &OperatorGroup{}, + &OperatorGroupList{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1/zz_generated.deepcopy.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1/zz_generated.deepcopy.go new file mode 100644 index 0000000000..7097508a6b --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1/zz_generated.deepcopy.go @@ -0,0 +1,136 @@ +// +build !ignore_autogenerated + +/* +Copyright 2019 Red Hat, 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 deepcopy-gen. DO NOT EDIT. + +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + 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 *OperatorGroup) DeepCopyInto(out *OperatorGroup) { + *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 OperatorGroup. +func (in *OperatorGroup) DeepCopy() *OperatorGroup { + if in == nil { + return nil + } + out := new(OperatorGroup) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *OperatorGroup) 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 *OperatorGroupList) DeepCopyInto(out *OperatorGroupList) { + *out = *in + out.TypeMeta = in.TypeMeta + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]OperatorGroup, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OperatorGroupList. +func (in *OperatorGroupList) DeepCopy() *OperatorGroupList { + if in == nil { + return nil + } + out := new(OperatorGroupList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *OperatorGroupList) 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 *OperatorGroupSpec) DeepCopyInto(out *OperatorGroupSpec) { + *out = *in + if in.Selector != nil { + in, out := &in.Selector, &out.Selector + *out = new(metav1.LabelSelector) + (*in).DeepCopyInto(*out) + } + if in.TargetNamespaces != nil { + in, out := &in.TargetNamespaces, &out.TargetNamespaces + *out = make([]string, len(*in)) + copy(*out, *in) + } + in.ServiceAccount.DeepCopyInto(&out.ServiceAccount) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OperatorGroupSpec. +func (in *OperatorGroupSpec) DeepCopy() *OperatorGroupSpec { + if in == nil { + return nil + } + out := new(OperatorGroupSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OperatorGroupStatus) DeepCopyInto(out *OperatorGroupStatus) { + *out = *in + if in.Namespaces != nil { + in, out := &in.Namespaces, &out.Namespaces + *out = make([]string, len(*in)) + copy(*out, *in) + } + in.LastUpdated.DeepCopyInto(&out.LastUpdated) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OperatorGroupStatus. +func (in *OperatorGroupStatus) DeepCopy() *OperatorGroupStatus { + if in == nil { + return nil + } + out := new(OperatorGroupStatus) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1/catalogsource_types.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1/catalogsource_types.go index cd285034ee..f12b332878 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1/catalogsource_types.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1/catalogsource_types.go @@ -1,9 +1,12 @@ package v1alpha1 import ( - "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators" + "fmt" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" + + "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators" ) const ( @@ -11,10 +14,47 @@ const ( CatalogSourceKind = "CatalogSource" ) +// SourceType indicates the type of backing store for a CatalogSource +type SourceType string + +const ( + // SourceTypeInternal (deprecated) specifies a CatalogSource of type SourceTypeConfigmap + SourceTypeInternal SourceType = "internal" + + // SourceTypeConfigmap specifies a CatalogSource that generates a configmap-server registry + SourceTypeConfigmap SourceType = "configmap" + + // SourceTypeGrpc specifies a CatalogSource that can use an operator registry image to generate a + // registry-server or connect to a pre-existing registry at an address. + SourceTypeGrpc SourceType = "grpc" +) + type CatalogSourceSpec struct { - SourceType string `json:"sourceType"` - ConfigMap string `json:"configMap,omitempty"` - Secrets []string `json:"secrets,omitempty"` + // SourceType is the type of source + SourceType SourceType `json:"sourceType"` + + // ConfigMap is the name of the ConfigMap to be used to back a configmap-server registry. + // Only used when SourceType = SourceTypeConfigmap or SourceTypeInternal. + // +Optional + ConfigMap string `json:"configMap,omitempty"` + + // Address is a host that OLM can use to connect to a pre-existing registry. + // Format: : + // Only used when SourceType = SourceTypeGrpc. + // Ignored when the Image field is set. + // +Optional + Address string `json:"address,omitempty"` + + // Image is an operator-registry container image to instantiate a registry-server with. + // Only used when SourceType = SourceTypeGrpc. + // If present, the address field is ignored. + // +Optional + Image string `json:"image,omitempty"` + + // Secrets represent set of secrets that can be used to access the contents of the catalog. + // It is best to keep this list small, since each will need to be tried for every catalog entry. + // +Optional + Secrets []string `json:"secrets,omitempty"` // Metadata DisplayName string `json:"displayName,omitempty"` @@ -23,10 +63,24 @@ type CatalogSourceSpec struct { Icon Icon `json:"icon,omitempty"` } +type RegistryServiceStatus struct { + Protocol string `json:"protocol,omitempty"` + ServiceName string `json:"serviceName,omitempty"` + ServiceNamespace string `json:"serviceNamespace,omitempty"` + Port string `json:"port,omitempty"` + CreatedAt metav1.Time `json:"createdAt,omitempty"` +} + +func (s *RegistryServiceStatus) Address() string { + return fmt.Sprintf("%s.%s.svc.cluster.local:%s", s.ServiceName, s.ServiceNamespace, s.Port) +} + type CatalogSourceStatus struct { - ConfigMapResource *ConfigMapResourceReference `json:"configMapReference,omitempty"` - LastSync metav1.Time `json:"lastSync,omitempty"` + ConfigMapResource *ConfigMapResourceReference `json:"configMapReference,omitempty"` + RegistryServiceStatus *RegistryServiceStatus `json:"registryService,omitempty"` + LastSync metav1.Time `json:"lastSync,omitempty"` } + type ConfigMapResourceReference struct { Name string `json:"name"` Namespace string `json:"namespace"` @@ -45,6 +99,13 @@ type CatalogSource struct { Status CatalogSourceStatus `json:"status"` } +func (c *CatalogSource) Address() string { + if c.Spec.Address != "" { + return c.Spec.Address + } + return c.Status.RegistryServiceStatus.Address() +} + // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object type CatalogSourceList struct { metav1.TypeMeta `json:",inline"` diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1/clusterserviceversion.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1/clusterserviceversion.go index 1972077218..6819ff5ef2 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1/clusterserviceversion.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1/clusterserviceversion.go @@ -1,7 +1,15 @@ package v1alpha1 import ( + "fmt" + + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/tools/record" +) + +const ( + CopiedLabelKey = "olm.copiedFrom" ) // obsoleteReasons are the set of reasons that mean a CSV should no longer be processed as active @@ -10,12 +18,59 @@ var obsoleteReasons = map[ConditionReason]struct{}{ CSVReasonBeingReplaced: {}, } +// uncopiableReasons are the set of reasons that should prevent a CSV from being copied to target namespaces +var uncopiableReasons = map[ConditionReason]struct{}{ + CSVReasonCopied: {}, + CSVReasonInvalidInstallModes: {}, + CSVReasonNoTargetNamespaces: {}, + CSVReasonUnsupportedOperatorGroup: {}, + CSVReasonNoOperatorGroup: {}, + CSVReasonTooManyOperatorGroups: {}, + CSVReasonInterOperatorGroupOwnerConflict: {}, + CSVReasonCannotModifyStaticOperatorGroupProvidedAPIs: {}, +} + +// safeToAnnotateOperatorGroupReasons are the set of reasons that it's safe to attempt to update the operatorgroup +// annotations +var safeToAnnotateOperatorGroupReasons = map[ConditionReason]struct{}{ + CSVReasonOwnerConflict: {}, + CSVReasonInstallSuccessful: {}, + CSVReasonInvalidInstallModes: {}, + CSVReasonNoTargetNamespaces: {}, + CSVReasonUnsupportedOperatorGroup: {}, + CSVReasonNoOperatorGroup: {}, + CSVReasonTooManyOperatorGroups: {}, + CSVReasonInterOperatorGroupOwnerConflict: {}, + CSVReasonCannotModifyStaticOperatorGroupProvidedAPIs: {}, +} + +// SetPhaseWithEventIfChanged emits a Kubernetes event with details of a phase change and sets the current phase if phase, reason, or message would changed +func (c *ClusterServiceVersion) SetPhaseWithEventIfChanged(phase ClusterServiceVersionPhase, reason ConditionReason, message string, now metav1.Time, recorder record.EventRecorder) { + if c.Status.Phase == phase && c.Status.Reason == reason && c.Status.Message == message { + return + } + + c.SetPhaseWithEvent(phase, reason, message, now, recorder) +} + +// SetPhaseWithEvent generates a Kubernetes event with details about the phase change and sets the current phase +func (c *ClusterServiceVersion) SetPhaseWithEvent(phase ClusterServiceVersionPhase, reason ConditionReason, message string, now metav1.Time, recorder record.EventRecorder) { + var eventtype string + if phase == CSVPhaseFailed { + eventtype = v1.EventTypeWarning + } else { + eventtype = v1.EventTypeNormal + } + go recorder.Event(c, eventtype, string(reason), message) + c.SetPhase(phase, reason, message, now) +} + // SetPhase sets the current phase and adds a condition if necessary -func (c *ClusterServiceVersion) SetPhase(phase ClusterServiceVersionPhase, reason ConditionReason, message string) { - c.Status.LastUpdateTime = metav1.Now() +func (c *ClusterServiceVersion) SetPhase(phase ClusterServiceVersionPhase, reason ConditionReason, message string, now metav1.Time) { + c.Status.LastUpdateTime = now if c.Status.Phase != phase { c.Status.Phase = phase - c.Status.LastTransitionTime = metav1.Now() + c.Status.LastTransitionTime = now } c.Status.Message = message c.Status.Reason = reason @@ -55,3 +110,83 @@ func (c *ClusterServiceVersion) IsObsolete() bool { } return false } + +// IsCopied returns true if the CSV has been copied and false otherwise. +func (c *ClusterServiceVersion) IsCopied() bool { + operatorNamespace, ok := c.GetAnnotations()[OperatorGroupNamespaceAnnotationKey] + if c.Status.Reason == CSVReasonCopied || ok && c.GetNamespace() != operatorNamespace { + return true + } + + if labels := c.GetLabels(); labels != nil { + if _, ok := labels[CopiedLabelKey]; ok { + return true + } + } + return false +} + +func (c *ClusterServiceVersion) IsUncopiable() bool { + if c.Status.Phase == CSVPhaseNone { + return true + } + _, ok := uncopiableReasons[c.Status.Reason] + return ok +} + +func (c *ClusterServiceVersion) IsSafeToUpdateOperatorGroupAnnotations() bool { + _, ok := safeToAnnotateOperatorGroupReasons[c.Status.Reason] + return ok +} + +// NewInstallModeSet returns an InstallModeSet instantiated from the given list of InstallModes. +// If the given list is not a set, an error is returned. +func NewInstallModeSet(modes []InstallMode) (InstallModeSet, error) { + set := InstallModeSet{} + for _, mode := range modes { + if _, exists := set[mode.Type]; exists { + return nil, fmt.Errorf("InstallMode list contains duplicates, cannot make set: %v", modes) + } + set[mode.Type] = mode.Supported + } + + return set, nil +} + +// Supports returns an error if the InstallModeSet does not support configuration for +// the given operatorNamespace and list of target namespaces. +func (set InstallModeSet) Supports(operatorNamespace string, namespaces []string) error { + numNamespaces := len(namespaces) + switch { + case numNamespaces == 0: + return fmt.Errorf("operatorgroup has invalid selected namespaces, cannot configure to watch zero namespaces") + case numNamespaces == 1: + switch namespaces[0] { + case operatorNamespace: + if !set[InstallModeTypeOwnNamespace] { + return fmt.Errorf("%s InstallModeType not supported, cannot configure to watch own namespace", InstallModeTypeOwnNamespace) + } + case v1.NamespaceAll: + if !set[InstallModeTypeAllNamespaces] { + return fmt.Errorf("%s InstallModeType not supported, cannot configure to watch all namespaces", InstallModeTypeAllNamespaces) + } + default: + if !set[InstallModeTypeSingleNamespace] { + return fmt.Errorf("%s InstallModeType not supported, cannot configure to watch one namespace", InstallModeTypeSingleNamespace) + } + } + case numNamespaces > 1 && !set[InstallModeTypeMultiNamespace]: + return fmt.Errorf("%s InstallModeType not supported, cannot configure to watch %d namespaces", InstallModeTypeMultiNamespace, numNamespaces) + case numNamespaces > 1: + for _, namespace := range namespaces { + if namespace == operatorNamespace && !set[InstallModeTypeOwnNamespace] { + return fmt.Errorf("%s InstallModeType not supported, cannot configure to watch own namespace", InstallModeTypeOwnNamespace) + } + if namespace == v1.NamespaceAll { + return fmt.Errorf("operatorgroup has invalid selected namespaces, NamespaceAll found when |selected namespaces| > 1") + } + } + } + + return nil +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1/clusterserviceversion_types.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1/clusterserviceversion_types.go index 0581f2ba62..899497c543 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1/clusterserviceversion_types.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1/clusterserviceversion_types.go @@ -4,18 +4,45 @@ package v1alpha1 import ( "encoding/json" + "fmt" "sort" "github.com/coreos/go-semver/semver" - "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators" ) const ( - ClusterServiceVersionAPIVersion = operators.GroupName + "/" + GroupVersion - ClusterServiceVersionKind = "ClusterServiceVersion" + ClusterServiceVersionAPIVersion = operators.GroupName + "/" + GroupVersion + ClusterServiceVersionKind = "ClusterServiceVersion" + OperatorGroupNamespaceAnnotationKey = "olm.operatorNamespace" +) + +// InstallModeType is a supported type of install mode for CSV installation +type InstallModeType string + +const ( + // InstallModeTypeOwnNamespace indicates that the operator can be a member of an `OperatorGroup` that selects its own namespace. + InstallModeTypeOwnNamespace InstallModeType = "OwnNamespace" + // InstallModeTypeSingleNamespace indicates that the operator can be a member of an `OperatorGroup` that selects one namespace. + InstallModeTypeSingleNamespace InstallModeType = "SingleNamespace" + // InstallModeTypeMultiNamespace indicates that the operator can be a member of an `OperatorGroup` that selects more than one namespace. + InstallModeTypeMultiNamespace InstallModeType = "MultiNamespace" + // InstallModeTypeAllNamespaces indicates that the operator can be a member of an `OperatorGroup` that selects all namespaces (target namespace set is the empty string ""). + InstallModeTypeAllNamespaces InstallModeType = "AllNamespaces" ) +// InstallMode associates an InstallModeType with a flag representing if the CSV supports it +// +k8s:openapi-gen=true +type InstallMode struct { + Type InstallModeType `json:"type"` + Supported bool `json:"supported"` +} + +// InstallModeSet is a mapping of unique InstallModeTypes to whether they are supported. +type InstallModeSet map[InstallModeType]bool + // NamedInstallStrategy represents the block of an ClusterServiceVersion resource // where the install strategy is specified. type NamedInstallStrategy struct { @@ -23,7 +50,7 @@ type NamedInstallStrategy struct { StrategySpecRaw json.RawMessage `json:"spec,omitempty"` } -// StatusDescriptor describes a field in a status block of a CRD so that ALM can consume it +// StatusDescriptor describes a field in a status block of a CRD so that OLM can consume it type StatusDescriptor struct { Path string `json:"path"` DisplayName string `json:"displayName,omitempty"` @@ -32,7 +59,7 @@ type StatusDescriptor struct { Value *json.RawMessage `json:"value,omitempty"` } -// SpecDescriptor describes a field in a spec block of a CRD so that ALM can consume it +// SpecDescriptor describes a field in a spec block of a CRD so that OLM can consume it type SpecDescriptor struct { Path string `json:"path"` DisplayName string `json:"displayName,omitempty"` @@ -50,26 +77,47 @@ type ActionDescriptor struct { Value *json.RawMessage `json:"value,omitempty"` } -// CRDDescription provides details to ALM about the CRDs +// CRDDescription provides details to OLM about the CRDs type CRDDescription struct { Name string `json:"name"` Version string `json:"version"` Kind string `json:"kind"` DisplayName string `json:"displayName,omitempty"` Description string `json:"description,omitempty"` - Resources []CRDResourceReference `json:"resources,omitempty"` + Resources []APIResourceReference `json:"resources,omitempty"` + StatusDescriptors []StatusDescriptor `json:"statusDescriptors,omitempty"` + SpecDescriptors []SpecDescriptor `json:"specDescriptors,omitempty"` + ActionDescriptor []ActionDescriptor `json:"actionDescriptors,omitempty"` +} + +// APIServiceDescription provides details to OLM about apis provided via aggregation +type APIServiceDescription struct { + Name string `json:"name"` + Group string `json:"group"` + Version string `json:"version"` + Kind string `json:"kind"` + DeploymentName string `json:"deploymentName,omitempty"` + ContainerPort int32 `json:"containerPort,omitempty"` + DisplayName string `json:"displayName,omitempty"` + Description string `json:"description,omitempty"` + Resources []APIResourceReference `json:"resources,omitempty"` StatusDescriptors []StatusDescriptor `json:"statusDescriptors,omitempty"` SpecDescriptors []SpecDescriptor `json:"specDescriptors,omitempty"` ActionDescriptor []ActionDescriptor `json:"actionDescriptors,omitempty"` } -// CRDResourceReference is a Kubernetes resource type used by a custom resource -type CRDResourceReference struct { +// APIResourceReference is a Kubernetes resource type used by a custom resource +type APIResourceReference struct { Name string `json:"name"` Kind string `json:"kind"` Version string `json:"version"` } +// GetName returns the name of an APIService as derived from its group and version. +func (d APIServiceDescription) GetName() string { + return fmt.Sprintf("%s.%s", d.Version, d.Group) +} + // CustomResourceDefinitions declares all of the CRDs managed or required by // an operator being ran by ClusterServiceVersion. // @@ -79,13 +127,23 @@ type CustomResourceDefinitions struct { Required []CRDDescription `json:"required,omitempty"` } -// ClusterServiceVersionSpec declarations tell the ALM how to install an operator -// that can manage apps for given version and AppType. +// APIServiceDefinitions declares all of the extension apis managed or required by +// an operator being ran by ClusterServiceVersion. +type APIServiceDefinitions struct { + Owned []APIServiceDescription `json:"owned,omitempty"` + Required []APIServiceDescription `json:"required,omitempty"` +} + +// ClusterServiceVersionSpec declarations tell OLM how to install an operator +// that can manage apps for a given version. type ClusterServiceVersionSpec struct { InstallStrategy NamedInstallStrategy `json:"install"` Version semver.Version `json:"version,omitempty"` Maturity string `json:"maturity,omitempty"` CustomResourceDefinitions CustomResourceDefinitions `json:"customresourcedefinitions,omitempty"` + APIServiceDefinitions APIServiceDefinitions `json:"apiservicedefinitions,omitempty"` + NativeAPIs []metav1.GroupVersionKind `json:"nativeAPIs,omitempty"` + MinKubeVersion string `json:"minKubeVersion,omitempty"` DisplayName string `json:"displayName"` Description string `json:"description,omitempty"` Keywords []string `json:"keywords,omitempty"` @@ -94,6 +152,10 @@ type ClusterServiceVersionSpec struct { Links []AppLink `json:"links,omitempty"` Icon []Icon `json:"icon,omitempty"` + // InstallModes specify supported installation types + // +optional + InstallModes []InstallMode `json:"installModes,omitempty"` + // The name of a CSV this one replaces. Should match the `metadata.Name` field of the old CSV. // +optional Replaces string `json:"replaces,omitempty"` @@ -151,24 +213,39 @@ const ( CSVPhaseReplacing ClusterServiceVersionPhase = "Replacing" // CSVPhaseDeleting means that a CSV has been replaced by a new one and will be checked for safety before being deleted CSVPhaseDeleting ClusterServiceVersionPhase = "Deleting" + // CSVPhaseAny matches all other phases in CSV queries + CSVPhaseAny ClusterServiceVersionPhase = "" ) // ConditionReason is a camelcased reason for the state transition type ConditionReason string const ( - CSVReasonRequirementsUnknown ConditionReason = "RequirementsUnknown" - CSVReasonRequirementsNotMet ConditionReason = "RequirementsNotMet" - CSVReasonRequirementsMet ConditionReason = "AllRequirementsMet" - CSVReasonOwnerConflict ConditionReason = "OwnerConflict" - CSVReasonComponentFailed ConditionReason = "InstallComponentFailed" - CSVReasonInvalidStrategy ConditionReason = "InvalidInstallStrategy" - CSVReasonWaiting ConditionReason = "InstallWaiting" - CSVReasonInstallSuccessful ConditionReason = "InstallSucceeded" - CSVReasonInstallCheckFailed ConditionReason = "InstallCheckFailed" - CSVReasonComponentUnhealthy ConditionReason = "ComponentUnhealthy" - CSVReasonBeingReplaced ConditionReason = "BeingReplaced" - CSVReasonReplaced ConditionReason = "Replaced" + CSVReasonRequirementsUnknown ConditionReason = "RequirementsUnknown" + CSVReasonRequirementsNotMet ConditionReason = "RequirementsNotMet" + CSVReasonRequirementsMet ConditionReason = "AllRequirementsMet" + CSVReasonOwnerConflict ConditionReason = "OwnerConflict" + CSVReasonComponentFailed ConditionReason = "InstallComponentFailed" + CSVReasonInvalidStrategy ConditionReason = "InvalidInstallStrategy" + CSVReasonWaiting ConditionReason = "InstallWaiting" + CSVReasonInstallSuccessful ConditionReason = "InstallSucceeded" + CSVReasonInstallCheckFailed ConditionReason = "InstallCheckFailed" + CSVReasonComponentUnhealthy ConditionReason = "ComponentUnhealthy" + CSVReasonBeingReplaced ConditionReason = "BeingReplaced" + CSVReasonReplaced ConditionReason = "Replaced" + CSVReasonNeedsReinstall ConditionReason = "NeedsReinstall" + CSVReasonNeedsCertRotation ConditionReason = "NeedsCertRotation" + CSVReasonAPIServiceResourceIssue ConditionReason = "APIServiceResourceIssue" + CSVReasonAPIServiceResourcesNeedReinstall ConditionReason = "APIServiceResourcesNeedReinstall" + CSVReasonAPIServiceInstallFailed ConditionReason = "APIServiceInstallFailed" + CSVReasonCopied ConditionReason = "Copied" + CSVReasonInvalidInstallModes ConditionReason = "InvalidInstallModes" + CSVReasonNoTargetNamespaces ConditionReason = "NoTargetNamespaces" + CSVReasonUnsupportedOperatorGroup ConditionReason = "UnsupportedOperatorGroup" + CSVReasonNoOperatorGroup ConditionReason = "NoOperatorGroup" + CSVReasonTooManyOperatorGroups ConditionReason = "TooManyOperatorGroups" + CSVReasonInterOperatorGroupOwnerConflict ConditionReason = "InterOperatorGroupOwnerConflict" + CSVReasonCannotModifyStaticOperatorGroupProvidedAPIs ConditionReason = "CannotModifyStaticOperatorGroupProvidedAPIs" ) // Conditions appear in the status as a record of state transitions on the ClusterServiceVersion @@ -192,8 +269,8 @@ type ClusterServiceVersionCondition struct { // OwnsCRD determines whether the current CSV owns a paritcular CRD. func (csv ClusterServiceVersion) OwnsCRD(name string) bool { - for _, crdDescription := range csv.Spec.CustomResourceDefinitions.Owned { - if crdDescription.Name == name { + for _, desc := range csv.Spec.CustomResourceDefinitions.Owned { + if desc.Name == name { return true } } @@ -201,13 +278,50 @@ func (csv ClusterServiceVersion) OwnsCRD(name string) bool { return false } +// OwnsAPIService determines whether the current CSV owns a paritcular APIService. +func (csv ClusterServiceVersion) OwnsAPIService(name string) bool { + for _, desc := range csv.Spec.APIServiceDefinitions.Owned { + apiServiceName := fmt.Sprintf("%s.%s", desc.Version, desc.Group) + if apiServiceName == name { + return true + } + } + + return false +} + +// StatusReason is a camelcased reason for the status of a RequirementStatus or DependentStatus +type StatusReason string + +const ( + RequirementStatusReasonPresent StatusReason = "Present" + RequirementStatusReasonNotPresent StatusReason = "NotPresent" + RequirementStatusReasonPresentNotSatisfied StatusReason = "PresentNotSatisfied" + // The CRD is present but the Established condition is False (not available) + RequirementStatusReasonNotAvailable StatusReason = "PresentNotAvailable" + DependentStatusReasonSatisfied StatusReason = "Satisfied" + DependentStatusReasonNotSatisfied StatusReason = "NotSatisfied" +) + +// DependentStatus is the status for a dependent requirement (to prevent infinite nesting) +type DependentStatus struct { + Group string `json:"group"` + Version string `json:"version"` + Kind string `json:"kind"` + Status StatusReason `json:"status"` + UUID string `json:"uuid,omitempty"` + Message string `json:"message,omitempty"` +} + type RequirementStatus struct { - Group string `json:"group"` - Version string `json:"version"` - Kind string `json:"kind"` - Name string `json:"name"` - Status string `json:"status"` - UUID string `json:"uuid,omitempty"` + Group string `json:"group"` + Version string `json:"version"` + Kind string `json:"kind"` + Name string `json:"name"` + Status StatusReason `json:"status"` + Message string `json:"message"` + UUID string `json:"uuid,omitempty"` + Dependents []DependentStatus `json:"dependents,omitempty"` } // ClusterServiceVersionStatus represents information about the status of a pod. Status may trail the actual @@ -232,11 +346,17 @@ type ClusterServiceVersionStatus struct { Conditions []ClusterServiceVersionCondition `json:"conditions,omitempty"` // The status of each requirement for this CSV RequirementStatus []RequirementStatus `json:"requirementStatus,omitempty"` + // Last time the owned APIService certs were updated + // +optional + CertsLastUpdated metav1.Time `json:"certsLastUpdated,omitempty"` + // Time the owned APIService certs will rotate next + // +optional + CertsRotateAt metav1.Time `json:"certsRotateAt,omitempty"` } +// ClusterServiceVersion is a Custom Resource of type `ClusterServiceVersionSpec`. // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +genclient -// ClusterServiceVersion is a Custom Resource of type `ClusterServiceVersionSpec`. type ClusterServiceVersion struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata"` @@ -282,3 +402,92 @@ func (csv ClusterServiceVersion) GetAllCRDDescriptions() []CRDDescription { return descs } + +// GetAllAPIServiceDescriptions returns a deduplicated set of APIServiceDescriptions that is +// the union of the owned and required APIServiceDescriptions. +// +// Descriptions with the same name prefer the value in Owned. +// Descriptions are returned in alphabetical order. +func (csv ClusterServiceVersion) GetAllAPIServiceDescriptions() []APIServiceDescription { + set := make(map[string]APIServiceDescription) + for _, required := range csv.Spec.APIServiceDefinitions.Required { + name := fmt.Sprintf("%s.%s", required.Version, required.Group) + set[name] = required + } + + for _, owned := range csv.Spec.APIServiceDefinitions.Owned { + name := fmt.Sprintf("%s.%s", owned.Version, owned.Group) + set[name] = owned + } + + keys := make([]string, 0) + for key := range set { + keys = append(keys, key) + } + sort.StringSlice(keys).Sort() + + descs := make([]APIServiceDescription, 0) + for _, key := range keys { + descs = append(descs, set[key]) + } + + return descs +} + +// GetRequiredAPIServiceDescriptions returns a deduplicated set of required APIServiceDescriptions +// with the intersection of required and owned removed +// Equivalent to the set subtraction required - owned +// +// Descriptions are returned in alphabetical order. +func (csv ClusterServiceVersion) GetRequiredAPIServiceDescriptions() []APIServiceDescription { + set := make(map[string]APIServiceDescription) + for _, required := range csv.Spec.APIServiceDefinitions.Required { + name := fmt.Sprintf("%s.%s", required.Version, required.Group) + set[name] = required + } + + // Remove any shared owned from the set + for _, owned := range csv.Spec.APIServiceDefinitions.Owned { + name := fmt.Sprintf("%s.%s", owned.Version, owned.Group) + if _, ok := set[name]; ok { + delete(set, name) + } + } + + keys := make([]string, 0) + for key := range set { + keys = append(keys, key) + } + sort.StringSlice(keys).Sort() + + descs := make([]APIServiceDescription, 0) + for _, key := range keys { + descs = append(descs, set[key]) + } + + return descs +} + +// GetOwnedAPIServiceDescriptions returns a deduplicated set of owned APIServiceDescriptions +// +// Descriptions are returned in alphabetical order. +func (csv ClusterServiceVersion) GetOwnedAPIServiceDescriptions() []APIServiceDescription { + set := make(map[string]APIServiceDescription) + for _, owned := range csv.Spec.APIServiceDefinitions.Owned { + name := owned.GetName() + set[name] = owned + } + + keys := make([]string, 0) + for key := range set { + keys = append(keys, key) + } + sort.StringSlice(keys).Sort() + + descs := make([]APIServiceDescription, 0) + for _, key := range keys { + descs = append(descs, set[key]) + } + + return descs +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1/installplan_types.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1/installplan_types.go index 63eef23370..96a90b7c6a 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1/installplan_types.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1/installplan_types.go @@ -1,18 +1,11 @@ package v1alpha1 import ( - "bytes" "errors" "fmt" corev1 "k8s.io/api/core/v1" - rbacv1 "k8s.io/api/rbac/v1" - "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" - "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - k8sjson "k8s.io/apimachinery/pkg/runtime/serializer/json" - k8sscheme "k8s.io/client-go/kubernetes/scheme" "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators" ) @@ -92,7 +85,7 @@ type InstallPlanStatus struct { Phase InstallPlanPhase `json:"phase"` Conditions []InstallPlanCondition `json:"conditions,omitempty"` CatalogSources []string `json:"catalogSources"` - Plan []Step `json:"plan,omitempty"` + Plan []*Step `json:"plan,omitempty"` } // InstallPlanCondition represents the overall status of the execution of @@ -152,6 +145,47 @@ type Step struct { Status StepStatus `json:"status"` } +// ManifestsMatch returns true if the CSV manifests in the StepResources of the given list of steps +// matches those in the InstallPlanStatus. +func (s *InstallPlanStatus) CSVManifestsMatch(steps []*Step) bool { + if s.Plan == nil && steps == nil { + return true + } + if s.Plan == nil || steps == nil { + return false + } + + manifests := make(map[string]struct{}) + for _, step := range s.Plan { + resource := step.Resource + if resource.Kind != ClusterServiceVersionKind { + continue + } + manifests[resource.Manifest] = struct{}{} + } + + for _, step := range steps { + resource := step.Resource + if resource.Kind != ClusterServiceVersionKind { + continue + } + if _, ok := manifests[resource.Manifest]; !ok { + return false + } + delete(manifests, resource.Manifest) + } + + if len(manifests) == 0 { + return true + } + + return false +} + +func (s *Step) String() string { + return fmt.Sprintf("%s: %s (%s)", s.Resolving, s.Resource, s.Status) +} + // StepResource represents the status of a resource to be tracked by an // InstallPlan. type StepResource struct { @@ -164,94 +198,8 @@ type StepResource struct { Manifest string `json:"manifest,omitempty"` } -// NewStepResourceFromCSV creates an unresolved Step for the provided CSV. -func NewStepResourceFromCSV(csv *ClusterServiceVersion) (StepResource, error) { - csvScheme := runtime.NewScheme() - if err := AddToScheme(csvScheme); err != nil { - return StepResource{}, err - } - csvSerializer := k8sjson.NewSerializer(k8sjson.DefaultMetaFactory, csvScheme, csvScheme, true) - - var manifestCSV bytes.Buffer - if err := csvSerializer.Encode(csv, &manifestCSV); err != nil { - return StepResource{}, err - } - - step := StepResource{ - Name: csv.Name, - Kind: csv.Kind, - Group: csv.GroupVersionKind().Group, - Version: csv.GroupVersionKind().Version, - Manifest: manifestCSV.String(), - } - - return step, nil -} - -// NewStepResourceFromCRD creates an unresolved Step for the provided CRD. -func NewStepResourcesFromCRD(crd *v1beta1.CustomResourceDefinition) ([]StepResource, error) { - serScheme := runtime.NewScheme() - k8sscheme.AddToScheme(serScheme) - scheme.AddToScheme(serScheme) - serializer := k8sjson.NewSerializer(k8sjson.DefaultMetaFactory, serScheme, serScheme, true) - - var manifest bytes.Buffer - if err := serializer.Encode(crd, &manifest); err != nil { - return nil, err - } - - crdStep := StepResource{ - Name: crd.Name, - Kind: crd.Kind, - Group: crd.Spec.Group, - Version: crd.Spec.Version, - Manifest: manifest.String(), - } - - editRole := rbacv1.ClusterRole{ - ObjectMeta: metav1.ObjectMeta{ - Name: fmt.Sprintf("edit-%s-%s", crd.Name, crd.Spec.Version), - Labels: map[string]string{ - "rbac.authorization.k8s.io/aggregate-to-admin": "true", - "rbac.authorization.k8s.io/aggregate-to-edit": "true", - }, - }, - Rules: []rbacv1.PolicyRule{{Verbs: []string{"create", "update", "patch", "delete"}, APIGroups: []string{crd.Spec.Group}, Resources: []string{crd.Spec.Names.Plural}}}, - } - var editRoleManifest bytes.Buffer - if err := serializer.Encode(&editRole, &editRoleManifest); err != nil { - return nil, err - } - aggregatedEditClusterRoleStep := StepResource{ - Name: editRole.Name, - Kind: "ClusterRole", - Group: "rbac.authorization.k8s.io", - Version: "v1", - Manifest: editRoleManifest.String(), - } - - viewRole := rbacv1.ClusterRole{ - ObjectMeta: metav1.ObjectMeta{ - Name: fmt.Sprintf("view-%s-%s", crd.Name, crd.Spec.Version), - Labels: map[string]string{ - "rbac.authorization.k8s.io/aggregate-to-view": "true", - }, - }, - Rules: []rbacv1.PolicyRule{{Verbs: []string{"get", "list", "watch"}, APIGroups: []string{crd.Spec.Group}, Resources: []string{crd.Spec.Names.Plural}}}, - } - var viewRoleManifest bytes.Buffer - if err := serializer.Encode(&viewRole, &viewRoleManifest); err != nil { - return nil, err - } - aggregatedViewClusterRoleStep := StepResource{ - Name: viewRole.Name, - Kind: "ClusterRole", - Group: "rbac.authorization.k8s.io", - Version: "v1", - Manifest: viewRoleManifest.String(), - } - - return []StepResource{crdStep, aggregatedEditClusterRoleStep, aggregatedViewClusterRoleStep}, nil +func (r StepResource) String() string { + return fmt.Sprintf("%s[%s/%s/%s (%s/%s)]", r.Name, r.Group, r.Version, r.Kind, r.CatalogSource, r.CatalogSourceNamespace) } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1/register.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1/register.go index a3a5ced61d..764f10cd9e 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1/register.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1/register.go @@ -1,11 +1,10 @@ package v1alpha1 import ( + "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" - - "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators" ) const ( diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1/zz_generated.deepcopy.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1/zz_generated.deepcopy.go index f3509e73f1..b4b5c4ffe8 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1/zz_generated.deepcopy.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1/zz_generated.deepcopy.go @@ -1,7 +1,7 @@ // +build !ignore_autogenerated /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -27,6 +27,94 @@ 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 *APIResourceReference) DeepCopyInto(out *APIResourceReference) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIResourceReference. +func (in *APIResourceReference) DeepCopy() *APIResourceReference { + if in == nil { + return nil + } + out := new(APIResourceReference) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *APIServiceDefinitions) DeepCopyInto(out *APIServiceDefinitions) { + *out = *in + if in.Owned != nil { + in, out := &in.Owned, &out.Owned + *out = make([]APIServiceDescription, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Required != nil { + in, out := &in.Required, &out.Required + *out = make([]APIServiceDescription, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIServiceDefinitions. +func (in *APIServiceDefinitions) DeepCopy() *APIServiceDefinitions { + if in == nil { + return nil + } + out := new(APIServiceDefinitions) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *APIServiceDescription) DeepCopyInto(out *APIServiceDescription) { + *out = *in + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = make([]APIResourceReference, len(*in)) + copy(*out, *in) + } + if in.StatusDescriptors != nil { + in, out := &in.StatusDescriptors, &out.StatusDescriptors + *out = make([]StatusDescriptor, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.SpecDescriptors != nil { + in, out := &in.SpecDescriptors, &out.SpecDescriptors + *out = make([]SpecDescriptor, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.ActionDescriptor != nil { + in, out := &in.ActionDescriptor, &out.ActionDescriptor + *out = make([]ActionDescriptor, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIServiceDescription. +func (in *APIServiceDescription) DeepCopy() *APIServiceDescription { + if in == nil { + return nil + } + out := new(APIServiceDescription) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ActionDescriptor) DeepCopyInto(out *ActionDescriptor) { *out = *in @@ -37,15 +125,11 @@ func (in *ActionDescriptor) DeepCopyInto(out *ActionDescriptor) { } if in.Value != nil { in, out := &in.Value, &out.Value - if *in == nil { - *out = nil - } else { - *out = new(json.RawMessage) - if **in != nil { - in, out := *in, *out - *out = make([]byte, len(*in)) - copy(*out, *in) - } + *out = new(json.RawMessage) + if **in != nil { + in, out := *in, *out + *out = make([]byte, len(*in)) + copy(*out, *in) } } return @@ -82,7 +166,7 @@ func (in *CRDDescription) DeepCopyInto(out *CRDDescription) { *out = *in if in.Resources != nil { in, out := &in.Resources, &out.Resources - *out = make([]CRDResourceReference, len(*in)) + *out = make([]APIResourceReference, len(*in)) copy(*out, *in) } if in.StatusDescriptors != nil { @@ -119,22 +203,6 @@ func (in *CRDDescription) DeepCopy() *CRDDescription { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CRDResourceReference) DeepCopyInto(out *CRDResourceReference) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CRDResourceReference. -func (in *CRDResourceReference) DeepCopy() *CRDResourceReference { - if in == nil { - return nil - } - out := new(CRDResourceReference) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CatalogSource) DeepCopyInto(out *CatalogSource) { *out = *in @@ -223,12 +291,13 @@ func (in *CatalogSourceStatus) DeepCopyInto(out *CatalogSourceStatus) { *out = *in if in.ConfigMapResource != nil { in, out := &in.ConfigMapResource, &out.ConfigMapResource - if *in == nil { - *out = nil - } else { - *out = new(ConfigMapResourceReference) - **out = **in - } + *out = new(ConfigMapResourceReference) + **out = **in + } + if in.RegistryServiceStatus != nil { + in, out := &in.RegistryServiceStatus, &out.RegistryServiceStatus + *out = new(RegistryServiceStatus) + (*in).DeepCopyInto(*out) } in.LastSync.DeepCopyInto(&out.LastSync) return @@ -329,6 +398,12 @@ func (in *ClusterServiceVersionSpec) DeepCopyInto(out *ClusterServiceVersionSpec in.InstallStrategy.DeepCopyInto(&out.InstallStrategy) out.Version = in.Version in.CustomResourceDefinitions.DeepCopyInto(&out.CustomResourceDefinitions) + in.APIServiceDefinitions.DeepCopyInto(&out.APIServiceDefinitions) + if in.NativeAPIs != nil { + in, out := &in.NativeAPIs, &out.NativeAPIs + *out = make([]v1.GroupVersionKind, len(*in)) + copy(*out, *in) + } if in.Keywords != nil { in, out := &in.Keywords, &out.Keywords *out = make([]string, len(*in)) @@ -350,6 +425,11 @@ func (in *ClusterServiceVersionSpec) DeepCopyInto(out *ClusterServiceVersionSpec *out = make([]Icon, len(*in)) copy(*out, *in) } + if in.InstallModes != nil { + in, out := &in.InstallModes, &out.InstallModes + *out = make([]InstallMode, len(*in)) + copy(*out, *in) + } if in.Labels != nil { in, out := &in.Labels, &out.Labels *out = make(map[string]string, len(*in)) @@ -366,12 +446,8 @@ func (in *ClusterServiceVersionSpec) DeepCopyInto(out *ClusterServiceVersionSpec } if in.Selector != nil { in, out := &in.Selector, &out.Selector - if *in == nil { - *out = nil - } else { - *out = new(v1.LabelSelector) - (*in).DeepCopyInto(*out) - } + *out = new(v1.LabelSelector) + (*in).DeepCopyInto(*out) } return } @@ -401,8 +477,12 @@ func (in *ClusterServiceVersionStatus) DeepCopyInto(out *ClusterServiceVersionSt if in.RequirementStatus != nil { in, out := &in.RequirementStatus, &out.RequirementStatus *out = make([]RequirementStatus, len(*in)) - copy(*out, *in) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } + in.CertsLastUpdated.DeepCopyInto(&out.CertsLastUpdated) + in.CertsRotateAt.DeepCopyInto(&out.CertsRotateAt) return } @@ -462,6 +542,22 @@ func (in *CustomResourceDefinitions) DeepCopy() *CustomResourceDefinitions { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DependentStatus) DeepCopyInto(out *DependentStatus) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DependentStatus. +func (in *DependentStatus) DeepCopy() *DependentStatus { + if in == nil { + return nil + } + out := new(DependentStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Icon) DeepCopyInto(out *Icon) { *out = *in @@ -478,6 +574,44 @@ func (in *Icon) DeepCopy() *Icon { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstallMode) DeepCopyInto(out *InstallMode) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstallMode. +func (in *InstallMode) DeepCopy() *InstallMode { + if in == nil { + return nil + } + out := new(InstallMode) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in InstallModeSet) DeepCopyInto(out *InstallModeSet) { + { + in := &in + *out = make(InstallModeSet, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + return + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstallModeSet. +func (in InstallModeSet) DeepCopy() InstallModeSet { + if in == nil { + return nil + } + out := new(InstallModeSet) + in.DeepCopyInto(out) + return *out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *InstallPlan) DeepCopyInto(out *InstallPlan) { *out = *in @@ -611,8 +745,14 @@ func (in *InstallPlanStatus) DeepCopyInto(out *InstallPlanStatus) { } if in.Plan != nil { in, out := &in.Plan, &out.Plan - *out = make([]Step, len(*in)) - copy(*out, *in) + *out = make([]*Step, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(Step) + **out = **in + } + } } return } @@ -664,9 +804,31 @@ func (in *NamedInstallStrategy) DeepCopy() *NamedInstallStrategy { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RegistryServiceStatus) DeepCopyInto(out *RegistryServiceStatus) { + *out = *in + in.CreatedAt.DeepCopyInto(&out.CreatedAt) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RegistryServiceStatus. +func (in *RegistryServiceStatus) DeepCopy() *RegistryServiceStatus { + if in == nil { + return nil + } + out := new(RegistryServiceStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RequirementStatus) DeepCopyInto(out *RequirementStatus) { *out = *in + if in.Dependents != nil { + in, out := &in.Dependents, &out.Dependents + *out = make([]DependentStatus, len(*in)) + copy(*out, *in) + } return } @@ -690,15 +852,11 @@ func (in *SpecDescriptor) DeepCopyInto(out *SpecDescriptor) { } if in.Value != nil { in, out := &in.Value, &out.Value - if *in == nil { - *out = nil - } else { - *out = new(json.RawMessage) - if **in != nil { - in, out := *in, *out - *out = make([]byte, len(*in)) - copy(*out, *in) - } + *out = new(json.RawMessage) + if **in != nil { + in, out := *in, *out + *out = make([]byte, len(*in)) + copy(*out, *in) } } return @@ -724,15 +882,11 @@ func (in *StatusDescriptor) DeepCopyInto(out *StatusDescriptor) { } if in.Value != nil { in, out := &in.Value, &out.Value - if *in == nil { - *out = nil - } else { - *out = new(json.RawMessage) - if **in != nil { - in, out := *in, *out - *out = make([]byte, len(*in)) - copy(*out, *in) - } + *out = new(json.RawMessage) + if **in != nil { + in, out := *in, *out + *out = make([]byte, len(*in)) + copy(*out, *in) } } return @@ -788,12 +942,8 @@ func (in *Subscription) DeepCopyInto(out *Subscription) { in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) if in.Spec != nil { in, out := &in.Spec, &out.Spec - if *in == nil { - *out = nil - } else { - *out = new(SubscriptionSpec) - **out = **in - } + *out = new(SubscriptionSpec) + **out = **in } in.Status.DeepCopyInto(&out.Status) return @@ -871,12 +1021,8 @@ func (in *SubscriptionStatus) DeepCopyInto(out *SubscriptionStatus) { *out = *in if in.Install != nil { in, out := &in.Install, &out.Install - if *in == nil { - *out = nil - } else { - *out = new(InstallPlanReference) - **out = **in - } + *out = new(InstallPlanReference) + **out = **in } in.LastUpdated.DeepCopyInto(&out.LastUpdated) return diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/clientset.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/clientset.go index bd96eb1e1c..011b181754 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/clientset.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/clientset.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ limitations under the License. package versioned import ( + operatorsv1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1" operatorsv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1" discovery "k8s.io/client-go/discovery" rest "k8s.io/client-go/rest" @@ -28,8 +29,9 @@ import ( type Interface interface { Discovery() discovery.DiscoveryInterface OperatorsV1alpha1() operatorsv1alpha1.OperatorsV1alpha1Interface + OperatorsV1() operatorsv1.OperatorsV1Interface // Deprecated: please explicitly pick a version if possible. - Operators() operatorsv1alpha1.OperatorsV1alpha1Interface + Operators() operatorsv1.OperatorsV1Interface } // Clientset contains the clients for groups. Each group has exactly one @@ -37,6 +39,7 @@ type Interface interface { type Clientset struct { *discovery.DiscoveryClient operatorsV1alpha1 *operatorsv1alpha1.OperatorsV1alpha1Client + operatorsV1 *operatorsv1.OperatorsV1Client } // OperatorsV1alpha1 retrieves the OperatorsV1alpha1Client @@ -44,10 +47,15 @@ func (c *Clientset) OperatorsV1alpha1() operatorsv1alpha1.OperatorsV1alpha1Inter return c.operatorsV1alpha1 } +// OperatorsV1 retrieves the OperatorsV1Client +func (c *Clientset) OperatorsV1() operatorsv1.OperatorsV1Interface { + return c.operatorsV1 +} + // Deprecated: Operators retrieves the default version of OperatorsClient. // Please explicitly pick a version. -func (c *Clientset) Operators() operatorsv1alpha1.OperatorsV1alpha1Interface { - return c.operatorsV1alpha1 +func (c *Clientset) Operators() operatorsv1.OperatorsV1Interface { + return c.operatorsV1 } // Discovery retrieves the DiscoveryClient @@ -70,6 +78,10 @@ func NewForConfig(c *rest.Config) (*Clientset, error) { if err != nil { return nil, err } + cs.operatorsV1, err = operatorsv1.NewForConfig(&configShallowCopy) + if err != nil { + return nil, err + } cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy) if err != nil { @@ -83,6 +95,7 @@ func NewForConfig(c *rest.Config) (*Clientset, error) { func NewForConfigOrDie(c *rest.Config) *Clientset { var cs Clientset cs.operatorsV1alpha1 = operatorsv1alpha1.NewForConfigOrDie(c) + cs.operatorsV1 = operatorsv1.NewForConfigOrDie(c) cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c) return &cs @@ -92,6 +105,7 @@ func NewForConfigOrDie(c *rest.Config) *Clientset { func New(c rest.Interface) *Clientset { var cs Clientset cs.operatorsV1alpha1 = operatorsv1alpha1.New(c) + cs.operatorsV1 = operatorsv1.New(c) cs.DiscoveryClient = discovery.NewDiscoveryClient(c) return &cs diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/doc.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/doc.go index 41721ca52d..b51d8e686b 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/doc.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/doc.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/fake/clientset_generated.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/fake/clientset_generated.go index 2432a97b7f..c188cb7609 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/fake/clientset_generated.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/fake/clientset_generated.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -20,6 +20,8 @@ package fake import ( clientset "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned" + operatorsv1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1" + fakeoperatorsv1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1/fake" operatorsv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1" fakeoperatorsv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/fake" "k8s.io/apimachinery/pkg/runtime" @@ -76,7 +78,12 @@ func (c *Clientset) OperatorsV1alpha1() operatorsv1alpha1.OperatorsV1alpha1Inter return &fakeoperatorsv1alpha1.FakeOperatorsV1alpha1{Fake: &c.Fake} } -// Operators retrieves the OperatorsV1alpha1Client -func (c *Clientset) Operators() operatorsv1alpha1.OperatorsV1alpha1Interface { - return &fakeoperatorsv1alpha1.FakeOperatorsV1alpha1{Fake: &c.Fake} +// OperatorsV1 retrieves the OperatorsV1Client +func (c *Clientset) OperatorsV1() operatorsv1.OperatorsV1Interface { + return &fakeoperatorsv1.FakeOperatorsV1{Fake: &c.Fake} +} + +// Operators retrieves the OperatorsV1Client +func (c *Clientset) Operators() operatorsv1.OperatorsV1Interface { + return &fakeoperatorsv1.FakeOperatorsV1{Fake: &c.Fake} } diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/fake/doc.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/fake/doc.go index 9b99e71670..ee22a9450f 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/fake/doc.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/fake/doc.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/fake/register.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/fake/register.go index 3f47492a50..a266a07711 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/fake/register.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/fake/register.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -19,20 +19,21 @@ limitations under the License. package fake import ( + operatorsv1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1" operatorsv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" 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) - -func init() { - v1.AddToGroupVersion(scheme, schema.GroupVersion{Version: "v1"}) - AddToScheme(scheme) +var localSchemeBuilder = runtime.SchemeBuilder{ + operatorsv1alpha1.AddToScheme, + operatorsv1.AddToScheme, } // AddToScheme adds all types of this clientset into the given scheme. This allows composition @@ -45,10 +46,13 @@ func init() { // ) // // kclientset, _ := kubernetes.NewForConfig(c) -// aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) +// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) // // After this, RawExtensions in Kubernetes types will serialize kube-aggregator types // correctly. -func AddToScheme(scheme *runtime.Scheme) { - operatorsv1alpha1.AddToScheme(scheme) +var AddToScheme = localSchemeBuilder.AddToScheme + +func init() { + v1.AddToGroupVersion(scheme, schema.GroupVersion{Version: "v1"}) + utilruntime.Must(AddToScheme(scheme)) } diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/scheme/doc.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/scheme/doc.go index 7dc3756168..25323d1083 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/scheme/doc.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/scheme/doc.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/scheme/register.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/scheme/register.go index 213c024cdb..5201762e83 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/scheme/register.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/scheme/register.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -19,20 +19,21 @@ limitations under the License. package scheme import ( + operatorsv1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1" operatorsv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" 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) - -func init() { - v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"}) - AddToScheme(Scheme) +var localSchemeBuilder = runtime.SchemeBuilder{ + operatorsv1alpha1.AddToScheme, + operatorsv1.AddToScheme, } // AddToScheme adds all types of this clientset into the given scheme. This allows composition @@ -45,10 +46,13 @@ func init() { // ) // // kclientset, _ := kubernetes.NewForConfig(c) -// aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) +// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) // // After this, RawExtensions in Kubernetes types will serialize kube-aggregator types // correctly. -func AddToScheme(scheme *runtime.Scheme) { - operatorsv1alpha1.AddToScheme(scheme) +var AddToScheme = localSchemeBuilder.AddToScheme + +func init() { + v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"}) + utilruntime.Must(AddToScheme(Scheme)) } diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1/doc.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1/doc.go new file mode 100644 index 0000000000..00df41cd1f --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2019 Red Hat, 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 client-gen. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v1 diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/packagemanifest/v1alpha1/fake/doc.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1/fake/doc.go similarity index 95% rename from vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/packagemanifest/v1alpha1/fake/doc.go rename to vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1/fake/doc.go index 16f4439906..da6f0eb8e5 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/packagemanifest/v1alpha1/fake/doc.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1/fake/doc.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1/fake/fake_operatorgroup.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1/fake/fake_operatorgroup.go new file mode 100644 index 0000000000..66cbe80d48 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1/fake/fake_operatorgroup.go @@ -0,0 +1,140 @@ +/* +Copyright 2019 Red Hat, 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 client-gen. DO NOT EDIT. + +package fake + +import ( + operatorsv1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + schema "k8s.io/apimachinery/pkg/runtime/schema" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeOperatorGroups implements OperatorGroupInterface +type FakeOperatorGroups struct { + Fake *FakeOperatorsV1 + ns string +} + +var operatorgroupsResource = schema.GroupVersionResource{Group: "operators.coreos.com", Version: "v1", Resource: "operatorgroups"} + +var operatorgroupsKind = schema.GroupVersionKind{Group: "operators.coreos.com", Version: "v1", Kind: "OperatorGroup"} + +// Get takes name of the operatorGroup, and returns the corresponding operatorGroup object, and an error if there is any. +func (c *FakeOperatorGroups) Get(name string, options v1.GetOptions) (result *operatorsv1.OperatorGroup, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(operatorgroupsResource, c.ns, name), &operatorsv1.OperatorGroup{}) + + if obj == nil { + return nil, err + } + return obj.(*operatorsv1.OperatorGroup), err +} + +// List takes label and field selectors, and returns the list of OperatorGroups that match those selectors. +func (c *FakeOperatorGroups) List(opts v1.ListOptions) (result *operatorsv1.OperatorGroupList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(operatorgroupsResource, operatorgroupsKind, c.ns, opts), &operatorsv1.OperatorGroupList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &operatorsv1.OperatorGroupList{ListMeta: obj.(*operatorsv1.OperatorGroupList).ListMeta} + for _, item := range obj.(*operatorsv1.OperatorGroupList).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 operatorGroups. +func (c *FakeOperatorGroups) Watch(opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(operatorgroupsResource, c.ns, opts)) + +} + +// Create takes the representation of a operatorGroup and creates it. Returns the server's representation of the operatorGroup, and an error, if there is any. +func (c *FakeOperatorGroups) Create(operatorGroup *operatorsv1.OperatorGroup) (result *operatorsv1.OperatorGroup, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(operatorgroupsResource, c.ns, operatorGroup), &operatorsv1.OperatorGroup{}) + + if obj == nil { + return nil, err + } + return obj.(*operatorsv1.OperatorGroup), err +} + +// Update takes the representation of a operatorGroup and updates it. Returns the server's representation of the operatorGroup, and an error, if there is any. +func (c *FakeOperatorGroups) Update(operatorGroup *operatorsv1.OperatorGroup) (result *operatorsv1.OperatorGroup, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(operatorgroupsResource, c.ns, operatorGroup), &operatorsv1.OperatorGroup{}) + + if obj == nil { + return nil, err + } + return obj.(*operatorsv1.OperatorGroup), 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 *FakeOperatorGroups) UpdateStatus(operatorGroup *operatorsv1.OperatorGroup) (*operatorsv1.OperatorGroup, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(operatorgroupsResource, "status", c.ns, operatorGroup), &operatorsv1.OperatorGroup{}) + + if obj == nil { + return nil, err + } + return obj.(*operatorsv1.OperatorGroup), err +} + +// Delete takes name of the operatorGroup and deletes it. Returns an error if one occurs. +func (c *FakeOperatorGroups) Delete(name string, options *v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteAction(operatorgroupsResource, c.ns, name), &operatorsv1.OperatorGroup{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeOperatorGroups) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(operatorgroupsResource, c.ns, listOptions) + + _, err := c.Fake.Invokes(action, &operatorsv1.OperatorGroupList{}) + return err +} + +// Patch applies the patch and returns the patched operatorGroup. +func (c *FakeOperatorGroups) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *operatorsv1.OperatorGroup, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(operatorgroupsResource, c.ns, name, data, subresources...), &operatorsv1.OperatorGroup{}) + + if obj == nil { + return nil, err + } + return obj.(*operatorsv1.OperatorGroup), err +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1/fake/fake_operators_client.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1/fake/fake_operators_client.go new file mode 100644 index 0000000000..c17c772ba8 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1/fake/fake_operators_client.go @@ -0,0 +1,40 @@ +/* +Copyright 2019 Red Hat, 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 client-gen. DO NOT EDIT. + +package fake + +import ( + v1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1" + rest "k8s.io/client-go/rest" + testing "k8s.io/client-go/testing" +) + +type FakeOperatorsV1 struct { + *testing.Fake +} + +func (c *FakeOperatorsV1) OperatorGroups(namespace string) v1.OperatorGroupInterface { + return &FakeOperatorGroups{c, namespace} +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *FakeOperatorsV1) RESTClient() rest.Interface { + var ret *rest.RESTClient + return ret +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1/generated_expansion.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1/generated_expansion.go new file mode 100644 index 0000000000..9140e192d8 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1/generated_expansion.go @@ -0,0 +1,21 @@ +/* +Copyright 2019 Red Hat, 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 client-gen. DO NOT EDIT. + +package v1 + +type OperatorGroupExpansion interface{} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1/operatorgroup.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1/operatorgroup.go new file mode 100644 index 0000000000..220d18e190 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1/operatorgroup.go @@ -0,0 +1,174 @@ +/* +Copyright 2019 Red Hat, 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 client-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1" + scheme "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/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" +) + +// OperatorGroupsGetter has a method to return a OperatorGroupInterface. +// A group's client should implement this interface. +type OperatorGroupsGetter interface { + OperatorGroups(namespace string) OperatorGroupInterface +} + +// OperatorGroupInterface has methods to work with OperatorGroup resources. +type OperatorGroupInterface interface { + Create(*v1.OperatorGroup) (*v1.OperatorGroup, error) + Update(*v1.OperatorGroup) (*v1.OperatorGroup, error) + UpdateStatus(*v1.OperatorGroup) (*v1.OperatorGroup, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteCollection(options *metav1.DeleteOptions, listOptions metav1.ListOptions) error + Get(name string, options metav1.GetOptions) (*v1.OperatorGroup, error) + List(opts metav1.ListOptions) (*v1.OperatorGroupList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1.OperatorGroup, err error) + OperatorGroupExpansion +} + +// operatorGroups implements OperatorGroupInterface +type operatorGroups struct { + client rest.Interface + ns string +} + +// newOperatorGroups returns a OperatorGroups +func newOperatorGroups(c *OperatorsV1Client, namespace string) *operatorGroups { + return &operatorGroups{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the operatorGroup, and returns the corresponding operatorGroup object, and an error if there is any. +func (c *operatorGroups) Get(name string, options metav1.GetOptions) (result *v1.OperatorGroup, err error) { + result = &v1.OperatorGroup{} + err = c.client.Get(). + Namespace(c.ns). + Resource("operatorgroups"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of OperatorGroups that match those selectors. +func (c *operatorGroups) List(opts metav1.ListOptions) (result *v1.OperatorGroupList, err error) { + result = &v1.OperatorGroupList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("operatorgroups"). + VersionedParams(&opts, scheme.ParameterCodec). + Do(). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested operatorGroups. +func (c *operatorGroups) Watch(opts metav1.ListOptions) (watch.Interface, error) { + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("operatorgroups"). + VersionedParams(&opts, scheme.ParameterCodec). + Watch() +} + +// Create takes the representation of a operatorGroup and creates it. Returns the server's representation of the operatorGroup, and an error, if there is any. +func (c *operatorGroups) Create(operatorGroup *v1.OperatorGroup) (result *v1.OperatorGroup, err error) { + result = &v1.OperatorGroup{} + err = c.client.Post(). + Namespace(c.ns). + Resource("operatorgroups"). + Body(operatorGroup). + Do(). + Into(result) + return +} + +// Update takes the representation of a operatorGroup and updates it. Returns the server's representation of the operatorGroup, and an error, if there is any. +func (c *operatorGroups) Update(operatorGroup *v1.OperatorGroup) (result *v1.OperatorGroup, err error) { + result = &v1.OperatorGroup{} + err = c.client.Put(). + Namespace(c.ns). + Resource("operatorgroups"). + Name(operatorGroup.Name). + Body(operatorGroup). + Do(). + 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 *operatorGroups) UpdateStatus(operatorGroup *v1.OperatorGroup) (result *v1.OperatorGroup, err error) { + result = &v1.OperatorGroup{} + err = c.client.Put(). + Namespace(c.ns). + Resource("operatorgroups"). + Name(operatorGroup.Name). + SubResource("status"). + Body(operatorGroup). + Do(). + Into(result) + return +} + +// Delete takes name of the operatorGroup and deletes it. Returns an error if one occurs. +func (c *operatorGroups) Delete(name string, options *metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("operatorgroups"). + Name(name). + Body(options). + Do(). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *operatorGroups) DeleteCollection(options *metav1.DeleteOptions, listOptions metav1.ListOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("operatorgroups"). + VersionedParams(&listOptions, scheme.ParameterCodec). + Body(options). + Do(). + Error() +} + +// Patch applies the patch and returns the patched operatorGroup. +func (c *operatorGroups) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1.OperatorGroup, err error) { + result = &v1.OperatorGroup{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("operatorgroups"). + SubResource(subresources...). + Name(name). + Body(data). + Do(). + Into(result) + return +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1/operators_client.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1/operators_client.go new file mode 100644 index 0000000000..4b7f10acae --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1/operators_client.go @@ -0,0 +1,90 @@ +/* +Copyright 2019 Red Hat, 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 client-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1" + "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/scheme" + serializer "k8s.io/apimachinery/pkg/runtime/serializer" + rest "k8s.io/client-go/rest" +) + +type OperatorsV1Interface interface { + RESTClient() rest.Interface + OperatorGroupsGetter +} + +// OperatorsV1Client is used to interact with features provided by the operators.coreos.com group. +type OperatorsV1Client struct { + restClient rest.Interface +} + +func (c *OperatorsV1Client) OperatorGroups(namespace string) OperatorGroupInterface { + return newOperatorGroups(c, namespace) +} + +// NewForConfig creates a new OperatorsV1Client for the given config. +func NewForConfig(c *rest.Config) (*OperatorsV1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientFor(&config) + if err != nil { + return nil, err + } + return &OperatorsV1Client{client}, nil +} + +// NewForConfigOrDie creates a new OperatorsV1Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *OperatorsV1Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new OperatorsV1Client for the given RESTClient. +func New(c rest.Interface) *OperatorsV1Client { + return &OperatorsV1Client{c} +} + +func setConfigDefaults(config *rest.Config) error { + gv := v1.SchemeGroupVersion + config.GroupVersion = &gv + config.APIPath = "/apis" + config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: scheme.Codecs} + + 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 *OperatorsV1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/catalogsource.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/catalogsource.go index 8195245a2f..4ccab676ad 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/catalogsource.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/catalogsource.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/clusterserviceversion.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/clusterserviceversion.go index 8b4866fb3b..a56a86a120 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/clusterserviceversion.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/clusterserviceversion.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/doc.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/doc.go index df51baa4d4..06a90bb0e0 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/doc.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/doc.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/fake/doc.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/fake/doc.go index 16f4439906..da6f0eb8e5 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/fake/doc.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/fake/doc.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/fake/fake_catalogsource.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/fake/fake_catalogsource.go index cac9eb900d..4e6ce7d6ad 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/fake/fake_catalogsource.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/fake/fake_catalogsource.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/fake/fake_clusterserviceversion.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/fake/fake_clusterserviceversion.go index f264a88992..167a364166 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/fake/fake_clusterserviceversion.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/fake/fake_clusterserviceversion.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/fake/fake_installplan.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/fake/fake_installplan.go index 4e8f879dd0..a54c1f66ac 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/fake/fake_installplan.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/fake/fake_installplan.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/fake/fake_operators_client.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/fake/fake_operators_client.go index 25b4be99b7..c1c55e4c46 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/fake/fake_operators_client.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/fake/fake_operators_client.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/fake/fake_subscription.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/fake/fake_subscription.go index 527bc9f597..cca3fa2f99 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/fake/fake_subscription.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/fake/fake_subscription.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/generated_expansion.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/generated_expansion.go index 2311410d3b..a5c22b6c0c 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/generated_expansion.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/generated_expansion.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/installplan.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/installplan.go index 6a5160fc43..1f7125e4c4 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/installplan.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/installplan.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/operators_client.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/operators_client.go index 8e727107cd..a608557bb0 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/operators_client.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/operators_client.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/subscription.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/subscription.go index 63a466567f..76adf6d79c 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/subscription.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1/subscription.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/factory.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/factory.go index cf69c3c4d0..97552af365 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/factory.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/factory.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/generic.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/generic.go index 6527f494ca..2491fee29e 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/generic.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/generic.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ package externalversions import ( "fmt" + v1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1" v1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" schema "k8s.io/apimachinery/pkg/runtime/schema" cache "k8s.io/client-go/tools/cache" @@ -52,7 +53,11 @@ func (f *genericInformer) Lister() cache.GenericLister { // TODO extend this to unknown resources with a client pool func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) { switch resource { - // Group=operators.coreos.com, Version=v1alpha1 + // Group=operators.coreos.com, Version=v1 + case v1.SchemeGroupVersion.WithResource("operatorgroups"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Operators().V1().OperatorGroups().Informer()}, nil + + // Group=operators.coreos.com, Version=v1alpha1 case v1alpha1.SchemeGroupVersion.WithResource("catalogsources"): return &genericInformer{resource: resource.GroupResource(), informer: f.Operators().V1alpha1().CatalogSources().Informer()}, nil case v1alpha1.SchemeGroupVersion.WithResource("clusterserviceversions"): diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/internalinterfaces/factory_interfaces.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/internalinterfaces/factory_interfaces.go index fc49555d0f..bab046d754 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/internalinterfaces/factory_interfaces.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/internalinterfaces/factory_interfaces.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/operators/interface.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/operators/interface.go index 1758289a88..07907a18f8 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/operators/interface.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/operators/interface.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ package operators import ( internalinterfaces "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/internalinterfaces" + v1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/operators/v1" v1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/operators/v1alpha1" ) @@ -27,6 +28,8 @@ import ( type Interface interface { // V1alpha1 provides access to shared informers for resources in V1alpha1. V1alpha1() v1alpha1.Interface + // V1 provides access to shared informers for resources in V1. + V1() v1.Interface } type group struct { @@ -44,3 +47,8 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList func (g *group) V1alpha1() v1alpha1.Interface { return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions) } + +// V1 returns a new v1.Interface. +func (g *group) V1() v1.Interface { + return v1.New(g.factory, g.namespace, g.tweakListOptions) +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/operators/v1/interface.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/operators/v1/interface.go new file mode 100644 index 0000000000..7ddd65c020 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/operators/v1/interface.go @@ -0,0 +1,45 @@ +/* +Copyright 2019 Red Hat, 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 informer-gen. DO NOT EDIT. + +package v1 + +import ( + internalinterfaces "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // OperatorGroups returns a OperatorGroupInformer. + OperatorGroups() OperatorGroupInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// OperatorGroups returns a OperatorGroupInformer. +func (v *version) OperatorGroups() OperatorGroupInformer { + return &operatorGroupInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/operators/v1/operatorgroup.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/operators/v1/operatorgroup.go new file mode 100644 index 0000000000..ea769041f7 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/operators/v1/operatorgroup.go @@ -0,0 +1,89 @@ +/* +Copyright 2019 Red Hat, 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 informer-gen. DO NOT EDIT. + +package v1 + +import ( + time "time" + + operatorsv1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1" + versioned "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned" + internalinterfaces "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/internalinterfaces" + v1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" +) + +// OperatorGroupInformer provides access to a shared informer and lister for +// OperatorGroups. +type OperatorGroupInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.OperatorGroupLister +} + +type operatorGroupInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewOperatorGroupInformer constructs a new informer for OperatorGroup type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewOperatorGroupInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredOperatorGroupInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredOperatorGroupInformer constructs a new informer for OperatorGroup type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredOperatorGroupInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.OperatorsV1().OperatorGroups(namespace).List(options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.OperatorsV1().OperatorGroups(namespace).Watch(options) + }, + }, + &operatorsv1.OperatorGroup{}, + resyncPeriod, + indexers, + ) +} + +func (f *operatorGroupInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredOperatorGroupInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *operatorGroupInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&operatorsv1.OperatorGroup{}, f.defaultInformer) +} + +func (f *operatorGroupInformer) Lister() v1.OperatorGroupLister { + return v1.NewOperatorGroupLister(f.Informer().GetIndexer()) +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/operators/v1alpha1/catalogsource.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/operators/v1alpha1/catalogsource.go index 3f52c1f6e9..1fd065515f 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/operators/v1alpha1/catalogsource.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/operators/v1alpha1/catalogsource.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -21,7 +21,7 @@ package v1alpha1 import ( time "time" - operators_v1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + operatorsv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" versioned "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned" internalinterfaces "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/internalinterfaces" v1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1alpha1" @@ -70,7 +70,7 @@ func NewFilteredCatalogSourceInformer(client versioned.Interface, namespace stri return client.OperatorsV1alpha1().CatalogSources(namespace).Watch(options) }, }, - &operators_v1alpha1.CatalogSource{}, + &operatorsv1alpha1.CatalogSource{}, resyncPeriod, indexers, ) @@ -81,7 +81,7 @@ func (f *catalogSourceInformer) defaultInformer(client versioned.Interface, resy } func (f *catalogSourceInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&operators_v1alpha1.CatalogSource{}, f.defaultInformer) + return f.factory.InformerFor(&operatorsv1alpha1.CatalogSource{}, f.defaultInformer) } func (f *catalogSourceInformer) Lister() v1alpha1.CatalogSourceLister { diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/operators/v1alpha1/clusterserviceversion.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/operators/v1alpha1/clusterserviceversion.go index 4f42ffad7b..66bed04fd7 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/operators/v1alpha1/clusterserviceversion.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/operators/v1alpha1/clusterserviceversion.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -21,7 +21,7 @@ package v1alpha1 import ( time "time" - operators_v1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + operatorsv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" versioned "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned" internalinterfaces "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/internalinterfaces" v1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1alpha1" @@ -70,7 +70,7 @@ func NewFilteredClusterServiceVersionInformer(client versioned.Interface, namesp return client.OperatorsV1alpha1().ClusterServiceVersions(namespace).Watch(options) }, }, - &operators_v1alpha1.ClusterServiceVersion{}, + &operatorsv1alpha1.ClusterServiceVersion{}, resyncPeriod, indexers, ) @@ -81,7 +81,7 @@ func (f *clusterServiceVersionInformer) defaultInformer(client versioned.Interfa } func (f *clusterServiceVersionInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&operators_v1alpha1.ClusterServiceVersion{}, f.defaultInformer) + return f.factory.InformerFor(&operatorsv1alpha1.ClusterServiceVersion{}, f.defaultInformer) } func (f *clusterServiceVersionInformer) Lister() v1alpha1.ClusterServiceVersionLister { diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/operators/v1alpha1/installplan.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/operators/v1alpha1/installplan.go index 2d3c76d453..2a6f6c0641 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/operators/v1alpha1/installplan.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/operators/v1alpha1/installplan.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -21,7 +21,7 @@ package v1alpha1 import ( time "time" - operators_v1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + operatorsv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" versioned "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned" internalinterfaces "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/internalinterfaces" v1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1alpha1" @@ -70,7 +70,7 @@ func NewFilteredInstallPlanInformer(client versioned.Interface, namespace string return client.OperatorsV1alpha1().InstallPlans(namespace).Watch(options) }, }, - &operators_v1alpha1.InstallPlan{}, + &operatorsv1alpha1.InstallPlan{}, resyncPeriod, indexers, ) @@ -81,7 +81,7 @@ func (f *installPlanInformer) defaultInformer(client versioned.Interface, resync } func (f *installPlanInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&operators_v1alpha1.InstallPlan{}, f.defaultInformer) + return f.factory.InformerFor(&operatorsv1alpha1.InstallPlan{}, f.defaultInformer) } func (f *installPlanInformer) Lister() v1alpha1.InstallPlanLister { diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/operators/v1alpha1/interface.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/operators/v1alpha1/interface.go index 9af49c4648..02406e5fd9 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/operators/v1alpha1/interface.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/operators/v1alpha1/interface.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/operators/v1alpha1/subscription.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/operators/v1alpha1/subscription.go index e594d91481..c978fafb1d 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/operators/v1alpha1/subscription.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/operators/v1alpha1/subscription.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -21,7 +21,7 @@ package v1alpha1 import ( time "time" - operators_v1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + operatorsv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" versioned "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned" internalinterfaces "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions/internalinterfaces" v1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1alpha1" @@ -70,7 +70,7 @@ func NewFilteredSubscriptionInformer(client versioned.Interface, namespace strin return client.OperatorsV1alpha1().Subscriptions(namespace).Watch(options) }, }, - &operators_v1alpha1.Subscription{}, + &operatorsv1alpha1.Subscription{}, resyncPeriod, indexers, ) @@ -81,7 +81,7 @@ func (f *subscriptionInformer) defaultInformer(client versioned.Interface, resyn } func (f *subscriptionInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&operators_v1alpha1.Subscription{}, f.defaultInformer) + return f.factory.InformerFor(&operatorsv1alpha1.Subscription{}, f.defaultInformer) } func (f *subscriptionInformer) Lister() v1alpha1.SubscriptionLister { diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1/expansion_generated.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1/expansion_generated.go new file mode 100644 index 0000000000..24e5c2d141 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1/expansion_generated.go @@ -0,0 +1,27 @@ +/* +Copyright 2019 Red Hat, 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 lister-gen. DO NOT EDIT. + +package v1 + +// OperatorGroupListerExpansion allows custom methods to be added to +// OperatorGroupLister. +type OperatorGroupListerExpansion interface{} + +// OperatorGroupNamespaceListerExpansion allows custom methods to be added to +// OperatorGroupNamespaceLister. +type OperatorGroupNamespaceListerExpansion interface{} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1/operatorgroup.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1/operatorgroup.go new file mode 100644 index 0000000000..f32f7ef2bc --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1/operatorgroup.go @@ -0,0 +1,94 @@ +/* +Copyright 2019 Red Hat, 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 lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// OperatorGroupLister helps list OperatorGroups. +type OperatorGroupLister interface { + // List lists all OperatorGroups in the indexer. + List(selector labels.Selector) (ret []*v1.OperatorGroup, err error) + // OperatorGroups returns an object that can list and get OperatorGroups. + OperatorGroups(namespace string) OperatorGroupNamespaceLister + OperatorGroupListerExpansion +} + +// operatorGroupLister implements the OperatorGroupLister interface. +type operatorGroupLister struct { + indexer cache.Indexer +} + +// NewOperatorGroupLister returns a new OperatorGroupLister. +func NewOperatorGroupLister(indexer cache.Indexer) OperatorGroupLister { + return &operatorGroupLister{indexer: indexer} +} + +// List lists all OperatorGroups in the indexer. +func (s *operatorGroupLister) List(selector labels.Selector) (ret []*v1.OperatorGroup, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.OperatorGroup)) + }) + return ret, err +} + +// OperatorGroups returns an object that can list and get OperatorGroups. +func (s *operatorGroupLister) OperatorGroups(namespace string) OperatorGroupNamespaceLister { + return operatorGroupNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// OperatorGroupNamespaceLister helps list and get OperatorGroups. +type OperatorGroupNamespaceLister interface { + // List lists all OperatorGroups in the indexer for a given namespace. + List(selector labels.Selector) (ret []*v1.OperatorGroup, err error) + // Get retrieves the OperatorGroup from the indexer for a given namespace and name. + Get(name string) (*v1.OperatorGroup, error) + OperatorGroupNamespaceListerExpansion +} + +// operatorGroupNamespaceLister implements the OperatorGroupNamespaceLister +// interface. +type operatorGroupNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all OperatorGroups in the indexer for a given namespace. +func (s operatorGroupNamespaceLister) List(selector labels.Selector) (ret []*v1.OperatorGroup, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.OperatorGroup)) + }) + return ret, err +} + +// Get retrieves the OperatorGroup from the indexer for a given namespace and name. +func (s operatorGroupNamespaceLister) Get(name string) (*v1.OperatorGroup, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("operatorgroup"), name) + } + return obj.(*v1.OperatorGroup), nil +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1alpha1/catalogsource.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1alpha1/catalogsource.go index 75894163d5..31ecf84c27 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1alpha1/catalogsource.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1alpha1/catalogsource.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1alpha1/clusterserviceversion.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1alpha1/clusterserviceversion.go index d1ca80d9a3..2923d3d301 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1alpha1/clusterserviceversion.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1alpha1/clusterserviceversion.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1alpha1/expansion_generated.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1alpha1/expansion_generated.go index 8c6cf66ee8..ca5ce60095 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1alpha1/expansion_generated.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1alpha1/expansion_generated.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1alpha1/installplan.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1alpha1/installplan.go index aa24e50245..f86250baa6 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1alpha1/installplan.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1alpha1/installplan.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1alpha1/subscription.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1alpha1/subscription.go index 8b12e3aa9e..a0cb7f2587 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1alpha1/subscription.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1alpha1/subscription.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/wrappers/deployment_install_client.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/wrappers/deployment_install_client.go index 5a1e8476a3..d612b06b3b 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/wrappers/deployment_install_client.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/wrappers/deployment_install_client.go @@ -2,21 +2,23 @@ package wrappers import ( - "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient" - "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil" "github.com/pkg/errors" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" - v1beta1rbac "k8s.io/api/rbac/v1beta1" + rbacv1 "k8s.io/api/rbac/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient" + "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister" + "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil" ) var ErrNilObject = errors.New("Bad object supplied: ") type InstallStrategyDeploymentInterface interface { - CreateRole(role *v1beta1rbac.Role) (*v1beta1rbac.Role, error) - CreateRoleBinding(roleBinding *v1beta1rbac.RoleBinding) (*v1beta1rbac.RoleBinding, error) + CreateRole(role *rbacv1.Role) (*rbacv1.Role, error) + CreateRoleBinding(roleBinding *rbacv1.RoleBinding) (*rbacv1.RoleBinding, error) EnsureServiceAccount(serviceAccount *corev1.ServiceAccount, owner ownerutil.Owner) (*corev1.ServiceAccount, error) CreateDeployment(deployment *appsv1.Deployment) (*appsv1.Deployment, error) CreateOrUpdateDeployment(deployment *appsv1.Deployment) (*appsv1.Deployment, error) @@ -27,24 +29,26 @@ type InstallStrategyDeploymentInterface interface { type InstallStrategyDeploymentClientForNamespace struct { opClient operatorclient.ClientInterface + opLister operatorlister.OperatorLister Namespace string } var _ InstallStrategyDeploymentInterface = &InstallStrategyDeploymentClientForNamespace{} -func NewInstallStrategyDeploymentClient(opClient operatorclient.ClientInterface, namespace string) InstallStrategyDeploymentInterface { +func NewInstallStrategyDeploymentClient(opClient operatorclient.ClientInterface, opLister operatorlister.OperatorLister, namespace string) InstallStrategyDeploymentInterface { return &InstallStrategyDeploymentClientForNamespace{ opClient: opClient, + opLister: opLister, Namespace: namespace, } } -func (c *InstallStrategyDeploymentClientForNamespace) CreateRole(role *v1beta1rbac.Role) (*v1beta1rbac.Role, error) { - return c.opClient.KubernetesInterface().RbacV1beta1().Roles(c.Namespace).Create(role) +func (c *InstallStrategyDeploymentClientForNamespace) CreateRole(role *rbacv1.Role) (*rbacv1.Role, error) { + return c.opClient.KubernetesInterface().RbacV1().Roles(c.Namespace).Create(role) } -func (c *InstallStrategyDeploymentClientForNamespace) CreateRoleBinding(roleBinding *v1beta1rbac.RoleBinding) (*v1beta1rbac.RoleBinding, error) { - return c.opClient.KubernetesInterface().RbacV1beta1().RoleBindings(c.Namespace).Create(roleBinding) +func (c *InstallStrategyDeploymentClientForNamespace) CreateRoleBinding(roleBinding *rbacv1.RoleBinding) (*rbacv1.RoleBinding, error) { + return c.opClient.KubernetesInterface().RbacV1().RoleBindings(c.Namespace).Create(roleBinding) } func (c *InstallStrategyDeploymentClientForNamespace) EnsureServiceAccount(serviceAccount *corev1.ServiceAccount, owner ownerutil.Owner) (*corev1.ServiceAccount, error) { @@ -52,7 +56,7 @@ func (c *InstallStrategyDeploymentClientForNamespace) EnsureServiceAccount(servi return nil, ErrNilObject } - foundAccount, err := c.opClient.GetServiceAccount(c.Namespace, serviceAccount.Name) + foundAccount, err := c.opLister.CoreV1().ServiceAccountLister().ServiceAccounts(c.Namespace).Get(serviceAccount.Name) if err != nil && !apierrors.IsNotFound(err) { return nil, errors.Wrap(err, "checking for existing serviceacccount failed") } @@ -96,14 +100,13 @@ func (c *InstallStrategyDeploymentClientForNamespace) CreateOrUpdateDeployment(d } func (c *InstallStrategyDeploymentClientForNamespace) GetServiceAccountByName(serviceAccountName string) (*corev1.ServiceAccount, error) { - return c.opClient.KubernetesInterface().CoreV1().ServiceAccounts(c.Namespace).Get(serviceAccountName, metav1.GetOptions{}) + return c.opLister.CoreV1().ServiceAccountLister().ServiceAccounts(c.Namespace).Get(serviceAccountName) } func (c *InstallStrategyDeploymentClientForNamespace) FindAnyDeploymentsMatchingNames(depNames []string) ([]*appsv1.Deployment, error) { var deployments []*appsv1.Deployment for _, depName := range depNames { - fetchedDep, err := c.opClient.GetDeployment(c.Namespace, depName) - + fetchedDep, err := c.opLister.AppsV1().DeploymentLister().Deployments(c.Namespace).Get(depName) if err == nil { deployments = append(deployments, fetchedDep) } else { diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/wrappers/wrappersfakes/fake_install_strategy_deployment_interface.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/wrappers/wrappersfakes/fake_install_strategy_deployment_interface.go index 78f535be94..be64191c31 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/wrappers/wrappersfakes/fake_install_strategy_deployment_interface.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/api/wrappers/wrappersfakes/fake_install_strategy_deployment_interface.go @@ -2,86 +2,72 @@ package wrappersfakes import ( - "sync" + sync "sync" - "github.com/operator-framework/operator-lifecycle-manager/pkg/api/wrappers" - "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - v1beta1rbac "k8s.io/api/rbac/v1beta1" + wrappers "github.com/operator-framework/operator-lifecycle-manager/pkg/api/wrappers" + ownerutil "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil" + v1 "k8s.io/api/apps/v1" + v1a "k8s.io/api/core/v1" + v1b "k8s.io/api/rbac/v1" ) type FakeInstallStrategyDeploymentInterface struct { - CreateRoleStub func(role *v1beta1rbac.Role) (*v1beta1rbac.Role, error) - createRoleMutex sync.RWMutex - createRoleArgsForCall []struct { - role *v1beta1rbac.Role - } - createRoleReturns struct { - result1 *v1beta1rbac.Role - result2 error - } - createRoleReturnsOnCall map[int]struct { - result1 *v1beta1rbac.Role - result2 error - } - CreateRoleBindingStub func(roleBinding *v1beta1rbac.RoleBinding) (*v1beta1rbac.RoleBinding, error) - createRoleBindingMutex sync.RWMutex - createRoleBindingArgsForCall []struct { - roleBinding *v1beta1rbac.RoleBinding + CreateDeploymentStub func(*v1.Deployment) (*v1.Deployment, error) + createDeploymentMutex sync.RWMutex + createDeploymentArgsForCall []struct { + arg1 *v1.Deployment } - createRoleBindingReturns struct { - result1 *v1beta1rbac.RoleBinding + createDeploymentReturns struct { + result1 *v1.Deployment result2 error } - createRoleBindingReturnsOnCall map[int]struct { - result1 *v1beta1rbac.RoleBinding + createDeploymentReturnsOnCall map[int]struct { + result1 *v1.Deployment result2 error } - EnsureServiceAccountStub func(serviceAccount *corev1.ServiceAccount, owner ownerutil.Owner) (*corev1.ServiceAccount, error) - ensureServiceAccountMutex sync.RWMutex - ensureServiceAccountArgsForCall []struct { - serviceAccount *corev1.ServiceAccount - owner ownerutil.Owner + CreateOrUpdateDeploymentStub func(*v1.Deployment) (*v1.Deployment, error) + createOrUpdateDeploymentMutex sync.RWMutex + createOrUpdateDeploymentArgsForCall []struct { + arg1 *v1.Deployment } - ensureServiceAccountReturns struct { - result1 *corev1.ServiceAccount + createOrUpdateDeploymentReturns struct { + result1 *v1.Deployment result2 error } - ensureServiceAccountReturnsOnCall map[int]struct { - result1 *corev1.ServiceAccount + createOrUpdateDeploymentReturnsOnCall map[int]struct { + result1 *v1.Deployment result2 error } - CreateDeploymentStub func(deployment *appsv1.Deployment) (*appsv1.Deployment, error) - createDeploymentMutex sync.RWMutex - createDeploymentArgsForCall []struct { - deployment *appsv1.Deployment + CreateRoleStub func(*v1b.Role) (*v1b.Role, error) + createRoleMutex sync.RWMutex + createRoleArgsForCall []struct { + arg1 *v1b.Role } - createDeploymentReturns struct { - result1 *appsv1.Deployment + createRoleReturns struct { + result1 *v1b.Role result2 error } - createDeploymentReturnsOnCall map[int]struct { - result1 *appsv1.Deployment + createRoleReturnsOnCall map[int]struct { + result1 *v1b.Role result2 error } - CreateOrUpdateDeploymentStub func(deployment *appsv1.Deployment) (*appsv1.Deployment, error) - createOrUpdateDeploymentMutex sync.RWMutex - createOrUpdateDeploymentArgsForCall []struct { - deployment *appsv1.Deployment + CreateRoleBindingStub func(*v1b.RoleBinding) (*v1b.RoleBinding, error) + createRoleBindingMutex sync.RWMutex + createRoleBindingArgsForCall []struct { + arg1 *v1b.RoleBinding } - createOrUpdateDeploymentReturns struct { - result1 *appsv1.Deployment + createRoleBindingReturns struct { + result1 *v1b.RoleBinding result2 error } - createOrUpdateDeploymentReturnsOnCall map[int]struct { - result1 *appsv1.Deployment + createRoleBindingReturnsOnCall map[int]struct { + result1 *v1b.RoleBinding result2 error } - DeleteDeploymentStub func(name string) error + DeleteDeploymentStub func(string) error deleteDeploymentMutex sync.RWMutex deleteDeploymentArgsForCall []struct { - name string + arg1 string } deleteDeploymentReturns struct { result1 error @@ -89,307 +75,318 @@ type FakeInstallStrategyDeploymentInterface struct { deleteDeploymentReturnsOnCall map[int]struct { result1 error } - GetServiceAccountByNameStub func(serviceAccountName string) (*corev1.ServiceAccount, error) - getServiceAccountByNameMutex sync.RWMutex - getServiceAccountByNameArgsForCall []struct { - serviceAccountName string + EnsureServiceAccountStub func(*v1a.ServiceAccount, ownerutil.Owner) (*v1a.ServiceAccount, error) + ensureServiceAccountMutex sync.RWMutex + ensureServiceAccountArgsForCall []struct { + arg1 *v1a.ServiceAccount + arg2 ownerutil.Owner } - getServiceAccountByNameReturns struct { - result1 *corev1.ServiceAccount + ensureServiceAccountReturns struct { + result1 *v1a.ServiceAccount result2 error } - getServiceAccountByNameReturnsOnCall map[int]struct { - result1 *corev1.ServiceAccount + ensureServiceAccountReturnsOnCall map[int]struct { + result1 *v1a.ServiceAccount result2 error } - FindAnyDeploymentsMatchingNamesStub func(depNames []string) ([]*appsv1.Deployment, error) + FindAnyDeploymentsMatchingNamesStub func([]string) ([]*v1.Deployment, error) findAnyDeploymentsMatchingNamesMutex sync.RWMutex findAnyDeploymentsMatchingNamesArgsForCall []struct { - depNames []string + arg1 []string } findAnyDeploymentsMatchingNamesReturns struct { - result1 []*appsv1.Deployment + result1 []*v1.Deployment result2 error } findAnyDeploymentsMatchingNamesReturnsOnCall map[int]struct { - result1 []*appsv1.Deployment + result1 []*v1.Deployment result2 error } - invocations map[string][][]interface{} - invocationsMutex sync.RWMutex -} - -func (fake *FakeInstallStrategyDeploymentInterface) CreateRole(role *v1beta1rbac.Role) (*v1beta1rbac.Role, error) { - fake.createRoleMutex.Lock() - ret, specificReturn := fake.createRoleReturnsOnCall[len(fake.createRoleArgsForCall)] - fake.createRoleArgsForCall = append(fake.createRoleArgsForCall, struct { - role *v1beta1rbac.Role - }{role}) - fake.recordInvocation("CreateRole", []interface{}{role}) - fake.createRoleMutex.Unlock() - if fake.CreateRoleStub != nil { - return fake.CreateRoleStub(role) - } - if specificReturn { - return ret.result1, ret.result2 + GetServiceAccountByNameStub func(string) (*v1a.ServiceAccount, error) + getServiceAccountByNameMutex sync.RWMutex + getServiceAccountByNameArgsForCall []struct { + arg1 string } - return fake.createRoleReturns.result1, fake.createRoleReturns.result2 -} - -func (fake *FakeInstallStrategyDeploymentInterface) CreateRoleCallCount() int { - fake.createRoleMutex.RLock() - defer fake.createRoleMutex.RUnlock() - return len(fake.createRoleArgsForCall) -} - -func (fake *FakeInstallStrategyDeploymentInterface) CreateRoleArgsForCall(i int) *v1beta1rbac.Role { - fake.createRoleMutex.RLock() - defer fake.createRoleMutex.RUnlock() - return fake.createRoleArgsForCall[i].role -} - -func (fake *FakeInstallStrategyDeploymentInterface) CreateRoleReturns(result1 *v1beta1rbac.Role, result2 error) { - fake.CreateRoleStub = nil - fake.createRoleReturns = struct { - result1 *v1beta1rbac.Role + getServiceAccountByNameReturns struct { + result1 *v1a.ServiceAccount result2 error - }{result1, result2} -} - -func (fake *FakeInstallStrategyDeploymentInterface) CreateRoleReturnsOnCall(i int, result1 *v1beta1rbac.Role, result2 error) { - fake.CreateRoleStub = nil - if fake.createRoleReturnsOnCall == nil { - fake.createRoleReturnsOnCall = make(map[int]struct { - result1 *v1beta1rbac.Role - result2 error - }) } - fake.createRoleReturnsOnCall[i] = struct { - result1 *v1beta1rbac.Role + getServiceAccountByNameReturnsOnCall map[int]struct { + result1 *v1a.ServiceAccount result2 error - }{result1, result2} + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex } -func (fake *FakeInstallStrategyDeploymentInterface) CreateRoleBinding(roleBinding *v1beta1rbac.RoleBinding) (*v1beta1rbac.RoleBinding, error) { - fake.createRoleBindingMutex.Lock() - ret, specificReturn := fake.createRoleBindingReturnsOnCall[len(fake.createRoleBindingArgsForCall)] - fake.createRoleBindingArgsForCall = append(fake.createRoleBindingArgsForCall, struct { - roleBinding *v1beta1rbac.RoleBinding - }{roleBinding}) - fake.recordInvocation("CreateRoleBinding", []interface{}{roleBinding}) - fake.createRoleBindingMutex.Unlock() - if fake.CreateRoleBindingStub != nil { - return fake.CreateRoleBindingStub(roleBinding) +func (fake *FakeInstallStrategyDeploymentInterface) CreateDeployment(arg1 *v1.Deployment) (*v1.Deployment, error) { + fake.createDeploymentMutex.Lock() + ret, specificReturn := fake.createDeploymentReturnsOnCall[len(fake.createDeploymentArgsForCall)] + fake.createDeploymentArgsForCall = append(fake.createDeploymentArgsForCall, struct { + arg1 *v1.Deployment + }{arg1}) + fake.recordInvocation("CreateDeployment", []interface{}{arg1}) + fake.createDeploymentMutex.Unlock() + if fake.CreateDeploymentStub != nil { + return fake.CreateDeploymentStub(arg1) } if specificReturn { return ret.result1, ret.result2 } - return fake.createRoleBindingReturns.result1, fake.createRoleBindingReturns.result2 + fakeReturns := fake.createDeploymentReturns + return fakeReturns.result1, fakeReturns.result2 } -func (fake *FakeInstallStrategyDeploymentInterface) CreateRoleBindingCallCount() int { - fake.createRoleBindingMutex.RLock() - defer fake.createRoleBindingMutex.RUnlock() - return len(fake.createRoleBindingArgsForCall) +func (fake *FakeInstallStrategyDeploymentInterface) CreateDeploymentCallCount() int { + fake.createDeploymentMutex.RLock() + defer fake.createDeploymentMutex.RUnlock() + return len(fake.createDeploymentArgsForCall) } -func (fake *FakeInstallStrategyDeploymentInterface) CreateRoleBindingArgsForCall(i int) *v1beta1rbac.RoleBinding { - fake.createRoleBindingMutex.RLock() - defer fake.createRoleBindingMutex.RUnlock() - return fake.createRoleBindingArgsForCall[i].roleBinding +func (fake *FakeInstallStrategyDeploymentInterface) CreateDeploymentCalls(stub func(*v1.Deployment) (*v1.Deployment, error)) { + fake.createDeploymentMutex.Lock() + defer fake.createDeploymentMutex.Unlock() + fake.CreateDeploymentStub = stub } -func (fake *FakeInstallStrategyDeploymentInterface) CreateRoleBindingReturns(result1 *v1beta1rbac.RoleBinding, result2 error) { - fake.CreateRoleBindingStub = nil - fake.createRoleBindingReturns = struct { - result1 *v1beta1rbac.RoleBinding +func (fake *FakeInstallStrategyDeploymentInterface) CreateDeploymentArgsForCall(i int) *v1.Deployment { + fake.createDeploymentMutex.RLock() + defer fake.createDeploymentMutex.RUnlock() + argsForCall := fake.createDeploymentArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FakeInstallStrategyDeploymentInterface) CreateDeploymentReturns(result1 *v1.Deployment, result2 error) { + fake.createDeploymentMutex.Lock() + defer fake.createDeploymentMutex.Unlock() + fake.CreateDeploymentStub = nil + fake.createDeploymentReturns = struct { + result1 *v1.Deployment result2 error }{result1, result2} } -func (fake *FakeInstallStrategyDeploymentInterface) CreateRoleBindingReturnsOnCall(i int, result1 *v1beta1rbac.RoleBinding, result2 error) { - fake.CreateRoleBindingStub = nil - if fake.createRoleBindingReturnsOnCall == nil { - fake.createRoleBindingReturnsOnCall = make(map[int]struct { - result1 *v1beta1rbac.RoleBinding +func (fake *FakeInstallStrategyDeploymentInterface) CreateDeploymentReturnsOnCall(i int, result1 *v1.Deployment, result2 error) { + fake.createDeploymentMutex.Lock() + defer fake.createDeploymentMutex.Unlock() + fake.CreateDeploymentStub = nil + if fake.createDeploymentReturnsOnCall == nil { + fake.createDeploymentReturnsOnCall = make(map[int]struct { + result1 *v1.Deployment result2 error }) } - fake.createRoleBindingReturnsOnCall[i] = struct { - result1 *v1beta1rbac.RoleBinding + fake.createDeploymentReturnsOnCall[i] = struct { + result1 *v1.Deployment result2 error }{result1, result2} } -func (fake *FakeInstallStrategyDeploymentInterface) EnsureServiceAccount(serviceAccount *corev1.ServiceAccount, owner ownerutil.Owner) (*corev1.ServiceAccount, error) { - fake.ensureServiceAccountMutex.Lock() - ret, specificReturn := fake.ensureServiceAccountReturnsOnCall[len(fake.ensureServiceAccountArgsForCall)] - fake.ensureServiceAccountArgsForCall = append(fake.ensureServiceAccountArgsForCall, struct { - serviceAccount *corev1.ServiceAccount - owner ownerutil.Owner - }{serviceAccount, owner}) - fake.recordInvocation("EnsureServiceAccount", []interface{}{serviceAccount, owner}) - fake.ensureServiceAccountMutex.Unlock() - if fake.EnsureServiceAccountStub != nil { - return fake.EnsureServiceAccountStub(serviceAccount, owner) +func (fake *FakeInstallStrategyDeploymentInterface) CreateOrUpdateDeployment(arg1 *v1.Deployment) (*v1.Deployment, error) { + fake.createOrUpdateDeploymentMutex.Lock() + ret, specificReturn := fake.createOrUpdateDeploymentReturnsOnCall[len(fake.createOrUpdateDeploymentArgsForCall)] + fake.createOrUpdateDeploymentArgsForCall = append(fake.createOrUpdateDeploymentArgsForCall, struct { + arg1 *v1.Deployment + }{arg1}) + fake.recordInvocation("CreateOrUpdateDeployment", []interface{}{arg1}) + fake.createOrUpdateDeploymentMutex.Unlock() + if fake.CreateOrUpdateDeploymentStub != nil { + return fake.CreateOrUpdateDeploymentStub(arg1) } if specificReturn { return ret.result1, ret.result2 } - return fake.ensureServiceAccountReturns.result1, fake.ensureServiceAccountReturns.result2 + fakeReturns := fake.createOrUpdateDeploymentReturns + return fakeReturns.result1, fakeReturns.result2 } -func (fake *FakeInstallStrategyDeploymentInterface) EnsureServiceAccountCallCount() int { - fake.ensureServiceAccountMutex.RLock() - defer fake.ensureServiceAccountMutex.RUnlock() - return len(fake.ensureServiceAccountArgsForCall) +func (fake *FakeInstallStrategyDeploymentInterface) CreateOrUpdateDeploymentCallCount() int { + fake.createOrUpdateDeploymentMutex.RLock() + defer fake.createOrUpdateDeploymentMutex.RUnlock() + return len(fake.createOrUpdateDeploymentArgsForCall) } -func (fake *FakeInstallStrategyDeploymentInterface) EnsureServiceAccountArgsForCall(i int) (*corev1.ServiceAccount, ownerutil.Owner) { - fake.ensureServiceAccountMutex.RLock() - defer fake.ensureServiceAccountMutex.RUnlock() - return fake.ensureServiceAccountArgsForCall[i].serviceAccount, fake.ensureServiceAccountArgsForCall[i].owner +func (fake *FakeInstallStrategyDeploymentInterface) CreateOrUpdateDeploymentCalls(stub func(*v1.Deployment) (*v1.Deployment, error)) { + fake.createOrUpdateDeploymentMutex.Lock() + defer fake.createOrUpdateDeploymentMutex.Unlock() + fake.CreateOrUpdateDeploymentStub = stub } -func (fake *FakeInstallStrategyDeploymentInterface) EnsureServiceAccountReturns(result1 *corev1.ServiceAccount, result2 error) { - fake.EnsureServiceAccountStub = nil - fake.ensureServiceAccountReturns = struct { - result1 *corev1.ServiceAccount +func (fake *FakeInstallStrategyDeploymentInterface) CreateOrUpdateDeploymentArgsForCall(i int) *v1.Deployment { + fake.createOrUpdateDeploymentMutex.RLock() + defer fake.createOrUpdateDeploymentMutex.RUnlock() + argsForCall := fake.createOrUpdateDeploymentArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FakeInstallStrategyDeploymentInterface) CreateOrUpdateDeploymentReturns(result1 *v1.Deployment, result2 error) { + fake.createOrUpdateDeploymentMutex.Lock() + defer fake.createOrUpdateDeploymentMutex.Unlock() + fake.CreateOrUpdateDeploymentStub = nil + fake.createOrUpdateDeploymentReturns = struct { + result1 *v1.Deployment result2 error }{result1, result2} } -func (fake *FakeInstallStrategyDeploymentInterface) EnsureServiceAccountReturnsOnCall(i int, result1 *corev1.ServiceAccount, result2 error) { - fake.EnsureServiceAccountStub = nil - if fake.ensureServiceAccountReturnsOnCall == nil { - fake.ensureServiceAccountReturnsOnCall = make(map[int]struct { - result1 *corev1.ServiceAccount +func (fake *FakeInstallStrategyDeploymentInterface) CreateOrUpdateDeploymentReturnsOnCall(i int, result1 *v1.Deployment, result2 error) { + fake.createOrUpdateDeploymentMutex.Lock() + defer fake.createOrUpdateDeploymentMutex.Unlock() + fake.CreateOrUpdateDeploymentStub = nil + if fake.createOrUpdateDeploymentReturnsOnCall == nil { + fake.createOrUpdateDeploymentReturnsOnCall = make(map[int]struct { + result1 *v1.Deployment result2 error }) } - fake.ensureServiceAccountReturnsOnCall[i] = struct { - result1 *corev1.ServiceAccount + fake.createOrUpdateDeploymentReturnsOnCall[i] = struct { + result1 *v1.Deployment result2 error }{result1, result2} } -func (fake *FakeInstallStrategyDeploymentInterface) CreateDeployment(deployment *appsv1.Deployment) (*appsv1.Deployment, error) { - fake.createDeploymentMutex.Lock() - ret, specificReturn := fake.createDeploymentReturnsOnCall[len(fake.createDeploymentArgsForCall)] - fake.createDeploymentArgsForCall = append(fake.createDeploymentArgsForCall, struct { - deployment *appsv1.Deployment - }{deployment}) - fake.recordInvocation("CreateDeployment", []interface{}{deployment}) - fake.createDeploymentMutex.Unlock() - if fake.CreateDeploymentStub != nil { - return fake.CreateDeploymentStub(deployment) +func (fake *FakeInstallStrategyDeploymentInterface) CreateRole(arg1 *v1b.Role) (*v1b.Role, error) { + fake.createRoleMutex.Lock() + ret, specificReturn := fake.createRoleReturnsOnCall[len(fake.createRoleArgsForCall)] + fake.createRoleArgsForCall = append(fake.createRoleArgsForCall, struct { + arg1 *v1b.Role + }{arg1}) + fake.recordInvocation("CreateRole", []interface{}{arg1}) + fake.createRoleMutex.Unlock() + if fake.CreateRoleStub != nil { + return fake.CreateRoleStub(arg1) } if specificReturn { return ret.result1, ret.result2 } - return fake.createDeploymentReturns.result1, fake.createDeploymentReturns.result2 + fakeReturns := fake.createRoleReturns + return fakeReturns.result1, fakeReturns.result2 } -func (fake *FakeInstallStrategyDeploymentInterface) CreateDeploymentCallCount() int { - fake.createDeploymentMutex.RLock() - defer fake.createDeploymentMutex.RUnlock() - return len(fake.createDeploymentArgsForCall) +func (fake *FakeInstallStrategyDeploymentInterface) CreateRoleCallCount() int { + fake.createRoleMutex.RLock() + defer fake.createRoleMutex.RUnlock() + return len(fake.createRoleArgsForCall) } -func (fake *FakeInstallStrategyDeploymentInterface) CreateDeploymentArgsForCall(i int) *appsv1.Deployment { - fake.createDeploymentMutex.RLock() - defer fake.createDeploymentMutex.RUnlock() - return fake.createDeploymentArgsForCall[i].deployment +func (fake *FakeInstallStrategyDeploymentInterface) CreateRoleCalls(stub func(*v1b.Role) (*v1b.Role, error)) { + fake.createRoleMutex.Lock() + defer fake.createRoleMutex.Unlock() + fake.CreateRoleStub = stub } -func (fake *FakeInstallStrategyDeploymentInterface) CreateDeploymentReturns(result1 *appsv1.Deployment, result2 error) { - fake.CreateDeploymentStub = nil - fake.createDeploymentReturns = struct { - result1 *appsv1.Deployment +func (fake *FakeInstallStrategyDeploymentInterface) CreateRoleArgsForCall(i int) *v1b.Role { + fake.createRoleMutex.RLock() + defer fake.createRoleMutex.RUnlock() + argsForCall := fake.createRoleArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FakeInstallStrategyDeploymentInterface) CreateRoleReturns(result1 *v1b.Role, result2 error) { + fake.createRoleMutex.Lock() + defer fake.createRoleMutex.Unlock() + fake.CreateRoleStub = nil + fake.createRoleReturns = struct { + result1 *v1b.Role result2 error }{result1, result2} } -func (fake *FakeInstallStrategyDeploymentInterface) CreateDeploymentReturnsOnCall(i int, result1 *appsv1.Deployment, result2 error) { - fake.CreateDeploymentStub = nil - if fake.createDeploymentReturnsOnCall == nil { - fake.createDeploymentReturnsOnCall = make(map[int]struct { - result1 *appsv1.Deployment +func (fake *FakeInstallStrategyDeploymentInterface) CreateRoleReturnsOnCall(i int, result1 *v1b.Role, result2 error) { + fake.createRoleMutex.Lock() + defer fake.createRoleMutex.Unlock() + fake.CreateRoleStub = nil + if fake.createRoleReturnsOnCall == nil { + fake.createRoleReturnsOnCall = make(map[int]struct { + result1 *v1b.Role result2 error }) } - fake.createDeploymentReturnsOnCall[i] = struct { - result1 *appsv1.Deployment + fake.createRoleReturnsOnCall[i] = struct { + result1 *v1b.Role result2 error }{result1, result2} } -func (fake *FakeInstallStrategyDeploymentInterface) CreateOrUpdateDeployment(deployment *appsv1.Deployment) (*appsv1.Deployment, error) { - fake.createOrUpdateDeploymentMutex.Lock() - ret, specificReturn := fake.createOrUpdateDeploymentReturnsOnCall[len(fake.createOrUpdateDeploymentArgsForCall)] - fake.createOrUpdateDeploymentArgsForCall = append(fake.createOrUpdateDeploymentArgsForCall, struct { - deployment *appsv1.Deployment - }{deployment}) - fake.recordInvocation("CreateOrUpdateDeployment", []interface{}{deployment}) - fake.createOrUpdateDeploymentMutex.Unlock() - if fake.CreateOrUpdateDeploymentStub != nil { - return fake.CreateOrUpdateDeploymentStub(deployment) +func (fake *FakeInstallStrategyDeploymentInterface) CreateRoleBinding(arg1 *v1b.RoleBinding) (*v1b.RoleBinding, error) { + fake.createRoleBindingMutex.Lock() + ret, specificReturn := fake.createRoleBindingReturnsOnCall[len(fake.createRoleBindingArgsForCall)] + fake.createRoleBindingArgsForCall = append(fake.createRoleBindingArgsForCall, struct { + arg1 *v1b.RoleBinding + }{arg1}) + fake.recordInvocation("CreateRoleBinding", []interface{}{arg1}) + fake.createRoleBindingMutex.Unlock() + if fake.CreateRoleBindingStub != nil { + return fake.CreateRoleBindingStub(arg1) } if specificReturn { return ret.result1, ret.result2 } - return fake.createOrUpdateDeploymentReturns.result1, fake.createOrUpdateDeploymentReturns.result2 + fakeReturns := fake.createRoleBindingReturns + return fakeReturns.result1, fakeReturns.result2 } -func (fake *FakeInstallStrategyDeploymentInterface) CreateOrUpdateDeploymentCallCount() int { - fake.createOrUpdateDeploymentMutex.RLock() - defer fake.createOrUpdateDeploymentMutex.RUnlock() - return len(fake.createOrUpdateDeploymentArgsForCall) +func (fake *FakeInstallStrategyDeploymentInterface) CreateRoleBindingCallCount() int { + fake.createRoleBindingMutex.RLock() + defer fake.createRoleBindingMutex.RUnlock() + return len(fake.createRoleBindingArgsForCall) } -func (fake *FakeInstallStrategyDeploymentInterface) CreateOrUpdateDeploymentArgsForCall(i int) *appsv1.Deployment { - fake.createOrUpdateDeploymentMutex.RLock() - defer fake.createOrUpdateDeploymentMutex.RUnlock() - return fake.createOrUpdateDeploymentArgsForCall[i].deployment +func (fake *FakeInstallStrategyDeploymentInterface) CreateRoleBindingCalls(stub func(*v1b.RoleBinding) (*v1b.RoleBinding, error)) { + fake.createRoleBindingMutex.Lock() + defer fake.createRoleBindingMutex.Unlock() + fake.CreateRoleBindingStub = stub } -func (fake *FakeInstallStrategyDeploymentInterface) CreateOrUpdateDeploymentReturns(result1 *appsv1.Deployment, result2 error) { - fake.CreateOrUpdateDeploymentStub = nil - fake.createOrUpdateDeploymentReturns = struct { - result1 *appsv1.Deployment +func (fake *FakeInstallStrategyDeploymentInterface) CreateRoleBindingArgsForCall(i int) *v1b.RoleBinding { + fake.createRoleBindingMutex.RLock() + defer fake.createRoleBindingMutex.RUnlock() + argsForCall := fake.createRoleBindingArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FakeInstallStrategyDeploymentInterface) CreateRoleBindingReturns(result1 *v1b.RoleBinding, result2 error) { + fake.createRoleBindingMutex.Lock() + defer fake.createRoleBindingMutex.Unlock() + fake.CreateRoleBindingStub = nil + fake.createRoleBindingReturns = struct { + result1 *v1b.RoleBinding result2 error }{result1, result2} } -func (fake *FakeInstallStrategyDeploymentInterface) CreateOrUpdateDeploymentReturnsOnCall(i int, result1 *appsv1.Deployment, result2 error) { - fake.CreateOrUpdateDeploymentStub = nil - if fake.createOrUpdateDeploymentReturnsOnCall == nil { - fake.createOrUpdateDeploymentReturnsOnCall = make(map[int]struct { - result1 *appsv1.Deployment +func (fake *FakeInstallStrategyDeploymentInterface) CreateRoleBindingReturnsOnCall(i int, result1 *v1b.RoleBinding, result2 error) { + fake.createRoleBindingMutex.Lock() + defer fake.createRoleBindingMutex.Unlock() + fake.CreateRoleBindingStub = nil + if fake.createRoleBindingReturnsOnCall == nil { + fake.createRoleBindingReturnsOnCall = make(map[int]struct { + result1 *v1b.RoleBinding result2 error }) } - fake.createOrUpdateDeploymentReturnsOnCall[i] = struct { - result1 *appsv1.Deployment + fake.createRoleBindingReturnsOnCall[i] = struct { + result1 *v1b.RoleBinding result2 error }{result1, result2} } -func (fake *FakeInstallStrategyDeploymentInterface) DeleteDeployment(name string) error { +func (fake *FakeInstallStrategyDeploymentInterface) DeleteDeployment(arg1 string) error { fake.deleteDeploymentMutex.Lock() ret, specificReturn := fake.deleteDeploymentReturnsOnCall[len(fake.deleteDeploymentArgsForCall)] fake.deleteDeploymentArgsForCall = append(fake.deleteDeploymentArgsForCall, struct { - name string - }{name}) - fake.recordInvocation("DeleteDeployment", []interface{}{name}) + arg1 string + }{arg1}) + fake.recordInvocation("DeleteDeployment", []interface{}{arg1}) fake.deleteDeploymentMutex.Unlock() if fake.DeleteDeploymentStub != nil { - return fake.DeleteDeploymentStub(name) + return fake.DeleteDeploymentStub(arg1) } if specificReturn { return ret.result1 } - return fake.deleteDeploymentReturns.result1 + fakeReturns := fake.deleteDeploymentReturns + return fakeReturns.result1 } func (fake *FakeInstallStrategyDeploymentInterface) DeleteDeploymentCallCount() int { @@ -398,13 +395,22 @@ func (fake *FakeInstallStrategyDeploymentInterface) DeleteDeploymentCallCount() return len(fake.deleteDeploymentArgsForCall) } +func (fake *FakeInstallStrategyDeploymentInterface) DeleteDeploymentCalls(stub func(string) error) { + fake.deleteDeploymentMutex.Lock() + defer fake.deleteDeploymentMutex.Unlock() + fake.DeleteDeploymentStub = stub +} + func (fake *FakeInstallStrategyDeploymentInterface) DeleteDeploymentArgsForCall(i int) string { fake.deleteDeploymentMutex.RLock() defer fake.deleteDeploymentMutex.RUnlock() - return fake.deleteDeploymentArgsForCall[i].name + argsForCall := fake.deleteDeploymentArgsForCall[i] + return argsForCall.arg1 } func (fake *FakeInstallStrategyDeploymentInterface) DeleteDeploymentReturns(result1 error) { + fake.deleteDeploymentMutex.Lock() + defer fake.deleteDeploymentMutex.Unlock() fake.DeleteDeploymentStub = nil fake.deleteDeploymentReturns = struct { result1 error @@ -412,6 +418,8 @@ func (fake *FakeInstallStrategyDeploymentInterface) DeleteDeploymentReturns(resu } func (fake *FakeInstallStrategyDeploymentInterface) DeleteDeploymentReturnsOnCall(i int, result1 error) { + fake.deleteDeploymentMutex.Lock() + defer fake.deleteDeploymentMutex.Unlock() fake.DeleteDeploymentStub = nil if fake.deleteDeploymentReturnsOnCall == nil { fake.deleteDeploymentReturnsOnCall = make(map[int]struct { @@ -423,77 +431,91 @@ func (fake *FakeInstallStrategyDeploymentInterface) DeleteDeploymentReturnsOnCal }{result1} } -func (fake *FakeInstallStrategyDeploymentInterface) GetServiceAccountByName(serviceAccountName string) (*corev1.ServiceAccount, error) { - fake.getServiceAccountByNameMutex.Lock() - ret, specificReturn := fake.getServiceAccountByNameReturnsOnCall[len(fake.getServiceAccountByNameArgsForCall)] - fake.getServiceAccountByNameArgsForCall = append(fake.getServiceAccountByNameArgsForCall, struct { - serviceAccountName string - }{serviceAccountName}) - fake.recordInvocation("GetServiceAccountByName", []interface{}{serviceAccountName}) - fake.getServiceAccountByNameMutex.Unlock() - if fake.GetServiceAccountByNameStub != nil { - return fake.GetServiceAccountByNameStub(serviceAccountName) +func (fake *FakeInstallStrategyDeploymentInterface) EnsureServiceAccount(arg1 *v1a.ServiceAccount, arg2 ownerutil.Owner) (*v1a.ServiceAccount, error) { + fake.ensureServiceAccountMutex.Lock() + ret, specificReturn := fake.ensureServiceAccountReturnsOnCall[len(fake.ensureServiceAccountArgsForCall)] + fake.ensureServiceAccountArgsForCall = append(fake.ensureServiceAccountArgsForCall, struct { + arg1 *v1a.ServiceAccount + arg2 ownerutil.Owner + }{arg1, arg2}) + fake.recordInvocation("EnsureServiceAccount", []interface{}{arg1, arg2}) + fake.ensureServiceAccountMutex.Unlock() + if fake.EnsureServiceAccountStub != nil { + return fake.EnsureServiceAccountStub(arg1, arg2) } if specificReturn { return ret.result1, ret.result2 } - return fake.getServiceAccountByNameReturns.result1, fake.getServiceAccountByNameReturns.result2 + fakeReturns := fake.ensureServiceAccountReturns + return fakeReturns.result1, fakeReturns.result2 } -func (fake *FakeInstallStrategyDeploymentInterface) GetServiceAccountByNameCallCount() int { - fake.getServiceAccountByNameMutex.RLock() - defer fake.getServiceAccountByNameMutex.RUnlock() - return len(fake.getServiceAccountByNameArgsForCall) +func (fake *FakeInstallStrategyDeploymentInterface) EnsureServiceAccountCallCount() int { + fake.ensureServiceAccountMutex.RLock() + defer fake.ensureServiceAccountMutex.RUnlock() + return len(fake.ensureServiceAccountArgsForCall) } -func (fake *FakeInstallStrategyDeploymentInterface) GetServiceAccountByNameArgsForCall(i int) string { - fake.getServiceAccountByNameMutex.RLock() - defer fake.getServiceAccountByNameMutex.RUnlock() - return fake.getServiceAccountByNameArgsForCall[i].serviceAccountName +func (fake *FakeInstallStrategyDeploymentInterface) EnsureServiceAccountCalls(stub func(*v1a.ServiceAccount, ownerutil.Owner) (*v1a.ServiceAccount, error)) { + fake.ensureServiceAccountMutex.Lock() + defer fake.ensureServiceAccountMutex.Unlock() + fake.EnsureServiceAccountStub = stub } -func (fake *FakeInstallStrategyDeploymentInterface) GetServiceAccountByNameReturns(result1 *corev1.ServiceAccount, result2 error) { - fake.GetServiceAccountByNameStub = nil - fake.getServiceAccountByNameReturns = struct { - result1 *corev1.ServiceAccount +func (fake *FakeInstallStrategyDeploymentInterface) EnsureServiceAccountArgsForCall(i int) (*v1a.ServiceAccount, ownerutil.Owner) { + fake.ensureServiceAccountMutex.RLock() + defer fake.ensureServiceAccountMutex.RUnlock() + argsForCall := fake.ensureServiceAccountArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2 +} + +func (fake *FakeInstallStrategyDeploymentInterface) EnsureServiceAccountReturns(result1 *v1a.ServiceAccount, result2 error) { + fake.ensureServiceAccountMutex.Lock() + defer fake.ensureServiceAccountMutex.Unlock() + fake.EnsureServiceAccountStub = nil + fake.ensureServiceAccountReturns = struct { + result1 *v1a.ServiceAccount result2 error }{result1, result2} } -func (fake *FakeInstallStrategyDeploymentInterface) GetServiceAccountByNameReturnsOnCall(i int, result1 *corev1.ServiceAccount, result2 error) { - fake.GetServiceAccountByNameStub = nil - if fake.getServiceAccountByNameReturnsOnCall == nil { - fake.getServiceAccountByNameReturnsOnCall = make(map[int]struct { - result1 *corev1.ServiceAccount +func (fake *FakeInstallStrategyDeploymentInterface) EnsureServiceAccountReturnsOnCall(i int, result1 *v1a.ServiceAccount, result2 error) { + fake.ensureServiceAccountMutex.Lock() + defer fake.ensureServiceAccountMutex.Unlock() + fake.EnsureServiceAccountStub = nil + if fake.ensureServiceAccountReturnsOnCall == nil { + fake.ensureServiceAccountReturnsOnCall = make(map[int]struct { + result1 *v1a.ServiceAccount result2 error }) } - fake.getServiceAccountByNameReturnsOnCall[i] = struct { - result1 *corev1.ServiceAccount + fake.ensureServiceAccountReturnsOnCall[i] = struct { + result1 *v1a.ServiceAccount result2 error }{result1, result2} } -func (fake *FakeInstallStrategyDeploymentInterface) FindAnyDeploymentsMatchingNames(depNames []string) ([]*appsv1.Deployment, error) { - var depNamesCopy []string - if depNames != nil { - depNamesCopy = make([]string, len(depNames)) - copy(depNamesCopy, depNames) +func (fake *FakeInstallStrategyDeploymentInterface) FindAnyDeploymentsMatchingNames(arg1 []string) ([]*v1.Deployment, error) { + var arg1Copy []string + if arg1 != nil { + arg1Copy = make([]string, len(arg1)) + copy(arg1Copy, arg1) } fake.findAnyDeploymentsMatchingNamesMutex.Lock() ret, specificReturn := fake.findAnyDeploymentsMatchingNamesReturnsOnCall[len(fake.findAnyDeploymentsMatchingNamesArgsForCall)] fake.findAnyDeploymentsMatchingNamesArgsForCall = append(fake.findAnyDeploymentsMatchingNamesArgsForCall, struct { - depNames []string - }{depNamesCopy}) - fake.recordInvocation("FindAnyDeploymentsMatchingNames", []interface{}{depNamesCopy}) + arg1 []string + }{arg1Copy}) + fake.recordInvocation("FindAnyDeploymentsMatchingNames", []interface{}{arg1Copy}) fake.findAnyDeploymentsMatchingNamesMutex.Unlock() if fake.FindAnyDeploymentsMatchingNamesStub != nil { - return fake.FindAnyDeploymentsMatchingNamesStub(depNames) + return fake.FindAnyDeploymentsMatchingNamesStub(arg1) } if specificReturn { return ret.result1, ret.result2 } - return fake.findAnyDeploymentsMatchingNamesReturns.result1, fake.findAnyDeploymentsMatchingNamesReturns.result2 + fakeReturns := fake.findAnyDeploymentsMatchingNamesReturns + return fakeReturns.result1, fakeReturns.result2 } func (fake *FakeInstallStrategyDeploymentInterface) FindAnyDeploymentsMatchingNamesCallCount() int { @@ -502,30 +524,104 @@ func (fake *FakeInstallStrategyDeploymentInterface) FindAnyDeploymentsMatchingNa return len(fake.findAnyDeploymentsMatchingNamesArgsForCall) } +func (fake *FakeInstallStrategyDeploymentInterface) FindAnyDeploymentsMatchingNamesCalls(stub func([]string) ([]*v1.Deployment, error)) { + fake.findAnyDeploymentsMatchingNamesMutex.Lock() + defer fake.findAnyDeploymentsMatchingNamesMutex.Unlock() + fake.FindAnyDeploymentsMatchingNamesStub = stub +} + func (fake *FakeInstallStrategyDeploymentInterface) FindAnyDeploymentsMatchingNamesArgsForCall(i int) []string { fake.findAnyDeploymentsMatchingNamesMutex.RLock() defer fake.findAnyDeploymentsMatchingNamesMutex.RUnlock() - return fake.findAnyDeploymentsMatchingNamesArgsForCall[i].depNames + argsForCall := fake.findAnyDeploymentsMatchingNamesArgsForCall[i] + return argsForCall.arg1 } -func (fake *FakeInstallStrategyDeploymentInterface) FindAnyDeploymentsMatchingNamesReturns(result1 []*appsv1.Deployment, result2 error) { +func (fake *FakeInstallStrategyDeploymentInterface) FindAnyDeploymentsMatchingNamesReturns(result1 []*v1.Deployment, result2 error) { + fake.findAnyDeploymentsMatchingNamesMutex.Lock() + defer fake.findAnyDeploymentsMatchingNamesMutex.Unlock() fake.FindAnyDeploymentsMatchingNamesStub = nil fake.findAnyDeploymentsMatchingNamesReturns = struct { - result1 []*appsv1.Deployment + result1 []*v1.Deployment result2 error }{result1, result2} } -func (fake *FakeInstallStrategyDeploymentInterface) FindAnyDeploymentsMatchingNamesReturnsOnCall(i int, result1 []*appsv1.Deployment, result2 error) { +func (fake *FakeInstallStrategyDeploymentInterface) FindAnyDeploymentsMatchingNamesReturnsOnCall(i int, result1 []*v1.Deployment, result2 error) { + fake.findAnyDeploymentsMatchingNamesMutex.Lock() + defer fake.findAnyDeploymentsMatchingNamesMutex.Unlock() fake.FindAnyDeploymentsMatchingNamesStub = nil if fake.findAnyDeploymentsMatchingNamesReturnsOnCall == nil { fake.findAnyDeploymentsMatchingNamesReturnsOnCall = make(map[int]struct { - result1 []*appsv1.Deployment + result1 []*v1.Deployment result2 error }) } fake.findAnyDeploymentsMatchingNamesReturnsOnCall[i] = struct { - result1 []*appsv1.Deployment + result1 []*v1.Deployment + result2 error + }{result1, result2} +} + +func (fake *FakeInstallStrategyDeploymentInterface) GetServiceAccountByName(arg1 string) (*v1a.ServiceAccount, error) { + fake.getServiceAccountByNameMutex.Lock() + ret, specificReturn := fake.getServiceAccountByNameReturnsOnCall[len(fake.getServiceAccountByNameArgsForCall)] + fake.getServiceAccountByNameArgsForCall = append(fake.getServiceAccountByNameArgsForCall, struct { + arg1 string + }{arg1}) + fake.recordInvocation("GetServiceAccountByName", []interface{}{arg1}) + fake.getServiceAccountByNameMutex.Unlock() + if fake.GetServiceAccountByNameStub != nil { + return fake.GetServiceAccountByNameStub(arg1) + } + if specificReturn { + return ret.result1, ret.result2 + } + fakeReturns := fake.getServiceAccountByNameReturns + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *FakeInstallStrategyDeploymentInterface) GetServiceAccountByNameCallCount() int { + fake.getServiceAccountByNameMutex.RLock() + defer fake.getServiceAccountByNameMutex.RUnlock() + return len(fake.getServiceAccountByNameArgsForCall) +} + +func (fake *FakeInstallStrategyDeploymentInterface) GetServiceAccountByNameCalls(stub func(string) (*v1a.ServiceAccount, error)) { + fake.getServiceAccountByNameMutex.Lock() + defer fake.getServiceAccountByNameMutex.Unlock() + fake.GetServiceAccountByNameStub = stub +} + +func (fake *FakeInstallStrategyDeploymentInterface) GetServiceAccountByNameArgsForCall(i int) string { + fake.getServiceAccountByNameMutex.RLock() + defer fake.getServiceAccountByNameMutex.RUnlock() + argsForCall := fake.getServiceAccountByNameArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FakeInstallStrategyDeploymentInterface) GetServiceAccountByNameReturns(result1 *v1a.ServiceAccount, result2 error) { + fake.getServiceAccountByNameMutex.Lock() + defer fake.getServiceAccountByNameMutex.Unlock() + fake.GetServiceAccountByNameStub = nil + fake.getServiceAccountByNameReturns = struct { + result1 *v1a.ServiceAccount + result2 error + }{result1, result2} +} + +func (fake *FakeInstallStrategyDeploymentInterface) GetServiceAccountByNameReturnsOnCall(i int, result1 *v1a.ServiceAccount, result2 error) { + fake.getServiceAccountByNameMutex.Lock() + defer fake.getServiceAccountByNameMutex.Unlock() + fake.GetServiceAccountByNameStub = nil + if fake.getServiceAccountByNameReturnsOnCall == nil { + fake.getServiceAccountByNameReturnsOnCall = make(map[int]struct { + result1 *v1a.ServiceAccount + result2 error + }) + } + fake.getServiceAccountByNameReturnsOnCall[i] = struct { + result1 *v1a.ServiceAccount result2 error }{result1, result2} } @@ -533,22 +629,22 @@ func (fake *FakeInstallStrategyDeploymentInterface) FindAnyDeploymentsMatchingNa func (fake *FakeInstallStrategyDeploymentInterface) Invocations() map[string][][]interface{} { fake.invocationsMutex.RLock() defer fake.invocationsMutex.RUnlock() - fake.createRoleMutex.RLock() - defer fake.createRoleMutex.RUnlock() - fake.createRoleBindingMutex.RLock() - defer fake.createRoleBindingMutex.RUnlock() - fake.ensureServiceAccountMutex.RLock() - defer fake.ensureServiceAccountMutex.RUnlock() fake.createDeploymentMutex.RLock() defer fake.createDeploymentMutex.RUnlock() fake.createOrUpdateDeploymentMutex.RLock() defer fake.createOrUpdateDeploymentMutex.RUnlock() + fake.createRoleMutex.RLock() + defer fake.createRoleMutex.RUnlock() + fake.createRoleBindingMutex.RLock() + defer fake.createRoleBindingMutex.RUnlock() fake.deleteDeploymentMutex.RLock() defer fake.deleteDeploymentMutex.RUnlock() - fake.getServiceAccountByNameMutex.RLock() - defer fake.getServiceAccountByNameMutex.RUnlock() + fake.ensureServiceAccountMutex.RLock() + defer fake.ensureServiceAccountMutex.RUnlock() fake.findAnyDeploymentsMatchingNamesMutex.RLock() defer fake.findAnyDeploymentsMatchingNamesMutex.RUnlock() + fake.getServiceAccountByNameMutex.RLock() + defer fake.getServiceAccountByNameMutex.RUnlock() copiedInvocations := map[string][][]interface{}{} for key, value := range fake.invocations { copiedInvocations[key] = value diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/annotator/annotator.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/annotator/annotator.go deleted file mode 100644 index 2100e084a2..0000000000 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/annotator/annotator.go +++ /dev/null @@ -1,162 +0,0 @@ -package annotator - -import ( - "encoding/json" - "fmt" - - "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/strategicpatch" -) - -// Annotator talks to kubernetes and adds annotations to objects. -type Annotator struct { - OpClient operatorclient.ClientInterface - Annotations map[string]string -} - -func NewAnnotator(opClient operatorclient.ClientInterface, annotations map[string]string) *Annotator { - return &Annotator{ - OpClient: opClient, - Annotations: annotations, - } -} - -// AnnotateNamespaces takes a list of namespace names and adds annotations to them -func (a *Annotator) AnnotateNamespaces(namespaceNames []string) error { - if a.Annotations == nil { - return nil - } - - namespaces, err := a.getNamespaces(namespaceNames) - if err != nil { - return err - } - - for _, n := range namespaces { - if err := a.AnnotateNamespace(&n); err != nil { - return err - } - } - - return nil -} - -// CleanNamespaceAnnotations takes a list of namespace names and removes annotations from them -func (a *Annotator) CleanNamespaceAnnotations(namespaceNames []string) error { - if a.Annotations == nil { - return nil - } - - namespaces, err := a.getNamespaces(namespaceNames) - if err != nil { - return err - } - - for _, n := range namespaces { - if err := a.CleanNamespaceAnnotation(&n); err != nil { - return err - } - } - - return nil -} - -// getNamespaces gets the set of Namespace API objects given a list of names -// if NamespaceAll is passed (""), all namespaces will be returned -func (a *Annotator) getNamespaces(namespaceNames []string) (namespaces []corev1.Namespace, err error) { - if len(namespaceNames) == 1 && namespaceNames[0] == corev1.NamespaceAll { - namespaceList, err := a.OpClient.KubernetesInterface().CoreV1().Namespaces().List(metav1.ListOptions{}) - if err != nil { - return nil, err - } - namespaces = namespaceList.Items - return namespaces, nil - } - for _, n := range namespaceNames { - namespace, err := a.OpClient.KubernetesInterface().CoreV1().Namespaces().Get(n, metav1.GetOptions{}) - if err != nil { - return nil, err - } - namespaces = append(namespaces, *namespace) - } - return namespaces, nil -} - -func (a *Annotator) AnnotateNamespace(namespace *corev1.Namespace) error { - originalName := namespace.GetName() - originalData, err := json.Marshal(namespace) - if err != nil { - return err - } - - if namespace.Annotations == nil { - namespace.Annotations = map[string]string{} - } - - for key, value := range a.Annotations { - if existing, ok := namespace.Annotations[key]; ok && existing != value { - return fmt.Errorf("attempted to annotate namespace %s with %s:%s, but already annotated by %s:%s", namespace.Name, key, value, key, existing) - } - namespace.Annotations[key] = value - } - - modifiedData, err := json.Marshal(namespace) - if err != nil { - return err - } - patchBytes, err := strategicpatch.CreateTwoWayMergePatch(originalData, modifiedData, corev1.Namespace{}) - if err != nil { - return fmt.Errorf("error creating patch for Namespace: %v", err) - } - _, err = a.OpClient.KubernetesInterface().CoreV1().Namespaces().Patch(originalName, types.StrategicMergePatchType, patchBytes) - if err != nil { - return err - } - return nil -} - -func (a *Annotator) CleanNamespaceAnnotation(namespace *corev1.Namespace) error { - originalName := namespace.GetName() - originalData, err := json.Marshal(namespace) - if err != nil { - return err - } - - if namespace.Annotations == nil { - namespace.Annotations = map[string]string{} - } - - annotations := map[string]string{} - for k, v := range namespace.Annotations { - annotations[k] = v - } - - for key, value := range a.Annotations { - if existing, ok := namespace.Annotations[key]; ok && existing != value { - return fmt.Errorf("attempted to clean annotation %s:%s from namespace %s, but found unexpected annotation %s:%s", key, value, namespace.Name, key, existing) - } else if !ok { - // no namespace key to remove - return nil - } - delete(annotations, key) - } - namespace.SetAnnotations(annotations) - - modifiedData, err := json.Marshal(namespace) - if err != nil { - return err - } - patchBytes, err := strategicpatch.CreateTwoWayMergePatch(originalData, modifiedData, corev1.Namespace{}) - if err != nil { - return fmt.Errorf("error creating patch for Namespace: %v", err) - } - fmt.Println(string(patchBytes)) - _, err = a.OpClient.KubernetesInterface().CoreV1().Namespaces().Patch(originalName, types.StrategicMergePatchType, patchBytes) - if err != nil { - return err - } - return nil -} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/certs/certs.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/certs/certs.go new file mode 100644 index 0000000000..3e59e0284e --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/certs/certs.go @@ -0,0 +1,193 @@ +package certs + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "crypto/sha256" + "crypto/x509" + "crypto/x509/pkix" + "encoding/hex" + "encoding/pem" + "fmt" + "math" + "math/big" + "time" +) + +// KeyPair stores an x509 certificate and its ECDSA private key +type KeyPair struct { + Cert *x509.Certificate + Priv *ecdsa.PrivateKey +} + +// ToPEM returns the PEM encoded cert pair +func (kp *KeyPair) ToPEM() (certPEM []byte, privPEM []byte, err error) { + // PEM encode private key + privDER, err := x509.MarshalECPrivateKey(kp.Priv) + if err != nil { + return + } + privBlock := &pem.Block{ + Type: "EC PRIVATE KEY", + Bytes: privDER, + } + privPEM = pem.EncodeToMemory(privBlock) + + // PEM encode cert + certBlock := &pem.Block{ + Type: "CERTIFICATE", + Bytes: kp.Cert.Raw, + } + certPEM = pem.EncodeToMemory(certBlock) + + return +} + +// GenerateCA generates a self-signed CA cert/key pair that expires in expiresIn days +func GenerateCA(notAfter time.Time, organization string) (*KeyPair, error) { + notBefore := time.Now() + if notAfter.Before(notBefore) { + return nil, fmt.Errorf("invalid notAfter: %s before %s", notAfter.String(), notBefore.String()) + } + + serial, err := rand.Int(rand.Reader, new(big.Int).SetInt64(math.MaxInt64)) + if err != nil { + return nil, err + } + + caDetails := &x509.Certificate{ + SerialNumber: serial, + Subject: pkix.Name{ + Organization: []string{organization}, + }, + NotBefore: notBefore, + NotAfter: notAfter, + IsCA: true, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}, + KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, + BasicConstraintsValid: true, + } + + privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + if err != nil { + return nil, err + } + + publicKey := &privateKey.PublicKey + certRaw, err := x509.CreateCertificate(rand.Reader, caDetails, caDetails, publicKey, privateKey) + if err != nil { + return nil, err + } + + cert, err := x509.ParseCertificate(certRaw) + if err != nil { + return nil, err + } + + ca := &KeyPair{ + Cert: cert, + Priv: privateKey, + } + + return ca, nil +} + +// CreateSignedServingPair creates a serving cert/key pair signed by the given ca +func CreateSignedServingPair(notAfter time.Time, organization string, ca *KeyPair, hosts []string) (*KeyPair, error) { + notBefore := time.Now() + if notAfter.Before(notBefore) { + return nil, fmt.Errorf("invalid notAfter: %s before %s", notAfter.String(), notBefore.String()) + } + + serial, err := rand.Int(rand.Reader, new(big.Int).SetInt64(math.MaxInt64)) + if err != nil { + return nil, err + } + + certDetails := &x509.Certificate{ + SerialNumber: serial, + Subject: pkix.Name{ + Organization: []string{organization}, + }, + NotBefore: notBefore, + NotAfter: notAfter, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}, + KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, + BasicConstraintsValid: true, + DNSNames: hosts, + } + + privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + if err != nil { + return nil, err + } + + publicKey := &privateKey.PublicKey + certRaw, err := x509.CreateCertificate(rand.Reader, certDetails, ca.Cert, publicKey, ca.Priv) + if err != nil { + return nil, err + } + + cert, err := x509.ParseCertificate(certRaw) + if err != nil { + return nil, err + } + + servingCert := &KeyPair{ + Cert: cert, + Priv: privateKey, + } + + return servingCert, nil +} + +// PEMToCert converts the PEM block of the given byte array to an x509 certificate +func PEMToCert(certPEM []byte) (*x509.Certificate, error) { + block, _ := pem.Decode(certPEM) + if block == nil { + return nil, fmt.Errorf("cert PEM empty") + } + + cert, err := x509.ParseCertificate(block.Bytes) + if err != nil { + return nil, err + } + + return cert, nil +} + +// VerifyCert checks that the given cert is signed and trusted by the given CA +func VerifyCert(ca, cert *x509.Certificate, host string) error { + roots := x509.NewCertPool() + roots.AddCert(ca) + + opts := x509.VerifyOptions{ + DNSName: host, + Roots: roots, + } + + if _, err := cert.Verify(opts); err != nil { + return err + } + + return nil +} + +// Active checks if the given cert is within its valid time window +func Active(cert *x509.Certificate) bool { + now := time.Now() + active := now.After(cert.NotBefore) && now.Before(cert.NotAfter) + return active +} + +// PEMHash returns a hash of the given PEM encoded cert +type PEMHash func(certPEM []byte) (hash string) + +// PEMSHA256 returns the hex encoded SHA 256 hash of the given PEM encoded cert +func PEMSHA256(certPEM []byte) (hash string) { + hasher := sha256.New() + hasher.Write(certPEM) + hash = hex.EncodeToString(hasher.Sum(nil)) + return +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/errors/errors.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/errors/errors.go index 5015f0869c..e94b7b7e7e 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/errors/errors.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/errors/errors.go @@ -10,6 +10,22 @@ type MultipleExistingCRDOwnersError struct { Namespace string } +type UnadoptableError struct { + resourceNamespace string + resourceName string +} + +func (err UnadoptableError) Error() string { + if err.resourceNamespace == "" { + return fmt.Sprintf("%s is unadoptable", err.resourceName) + } + return fmt.Sprintf("%s/%s is unadoptable", err.resourceNamespace, err.resourceName) +} + +func NewUnadoptableError(resourceNamespace, resourceName string) UnadoptableError { + return UnadoptableError{resourceNamespace, resourceName} +} + func (m MultipleExistingCRDOwnersError) Error() string { return fmt.Sprintf("Existing CSVs %v in namespace %s all claim to own CRD %s", m.CSVNames, m.Namespace, m.CRDName) } @@ -30,3 +46,14 @@ func IsMultipleExistingCRDOwnersError(err error) bool { return false } + +// GroupVersionKindNotFoundError occurs when we can't find an API via discovery +type GroupVersionKindNotFoundError struct { + Group string + Version string + Kind string +} + +func (g GroupVersionKindNotFoundError) Error() string { + return fmt.Sprintf("Unable to find GVK in discovery: %s %s %s", g.Group, g.Version, g.Kind) +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install/attributes_util.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install/attributes_util.go new file mode 100644 index 0000000000..9b5810dc53 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install/attributes_util.go @@ -0,0 +1,79 @@ +package install + +import ( + log "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + "k8s.io/apiserver/pkg/authentication/serviceaccount" + "k8s.io/apiserver/pkg/authentication/user" + "k8s.io/apiserver/pkg/authorization/authorizer" +) + +// toAttributesSet converts the given user, namespace, and PolicyRule into a set of Attributes expected. This is useful for checking +// if a composed set of Roles/RoleBindings satisfies a PolicyRule. +func toAttributesSet(user user.Info, namespace string, rule rbacv1.PolicyRule) []authorizer.Attributes { + set := map[authorizer.AttributesRecord]struct{}{} + + // add empty string for empty groups, resources, resource names, and non resource urls + groups := rule.APIGroups + if len(groups) == 0 { + groups = make([]string, 1) + } + resources := rule.Resources + if len(resources) == 0 { + resources = make([]string, 1) + } + names := rule.ResourceNames + if len(names) == 0 { + names = make([]string, 1) + } + nonResourceURLs := rule.NonResourceURLs + if len(nonResourceURLs) == 0 { + nonResourceURLs = make([]string, 1) + } + + for _, verb := range rule.Verbs { + for _, group := range groups { + for _, resource := range resources { + for _, name := range names { + for _, nonResourceURL := range nonResourceURLs { + set[attributesRecord(user, namespace, verb, group, resource, name, nonResourceURL)] = struct{}{} + } + } + } + } + } + + attributes := make([]authorizer.Attributes, len(set)) + i := 0 + for attribute := range set { + attributes[i] = attribute + i++ + } + log.Debugf("attributes set %+v", attributes) + + return attributes +} + +// attribute creates a new AttributesRecord with the given info. Currently RBAC authz only looks at user, verb, apiGroup, resource, and name. +func attributesRecord(user user.Info, namespace, verb, apiGroup, resource, name, path string) authorizer.AttributesRecord { + resourceRequest := path == "" + return authorizer.AttributesRecord{ + User: user, + Verb: verb, + Namespace: namespace, + APIGroup: apiGroup, + Resource: resource, + Name: name, + ResourceRequest: resourceRequest, + Path: path, + } +} + +func toDefaultInfo(sa *corev1.ServiceAccount) *user.DefaultInfo { + // TODO(Nick): add Group if necessary + return &user.DefaultInfo{ + Name: serviceaccount.MakeUsername(sa.GetNamespace(), sa.GetName()), + UID: string(sa.GetUID()), + } +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install/deployment.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install/deployment.go index be5a9b84c4..c76341bd41 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install/deployment.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install/deployment.go @@ -5,9 +5,7 @@ import ( log "github.com/sirupsen/logrus" appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - rbac "k8s.io/api/rbac/v1beta1" - apierrors "k8s.io/apimachinery/pkg/api/errors" + rbac "k8s.io/api/rbac/v1" "github.com/operator-framework/operator-lifecycle-manager/pkg/api/wrappers" "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil" @@ -32,14 +30,16 @@ type StrategyDeploymentSpec struct { // StrategyDetailsDeployment represents the parsed details of a Deployment // InstallStrategy. type StrategyDetailsDeployment struct { - DeploymentSpecs []StrategyDeploymentSpec `json:"deployments"` - Permissions []StrategyDeploymentPermissions `json:"permissions,omitempty"` + DeploymentSpecs []StrategyDeploymentSpec `json:"deployments"` + Permissions []StrategyDeploymentPermissions `json:"permissions,omitempty"` + ClusterPermissions []StrategyDeploymentPermissions `json:"clusterPermissions,omitempty"` } type StrategyDeploymentInstaller struct { - strategyClient wrappers.InstallStrategyDeploymentInterface - owner ownerutil.Owner - previousStrategy Strategy + strategyClient wrappers.InstallStrategyDeploymentInterface + owner ownerutil.Owner + previousStrategy Strategy + templateAnnotations map[string]string } func (d *StrategyDetailsDeployment) GetStrategyName() string { @@ -49,70 +49,35 @@ func (d *StrategyDetailsDeployment) GetStrategyName() string { var _ Strategy = &StrategyDetailsDeployment{} var _ StrategyInstaller = &StrategyDeploymentInstaller{} -func NewStrategyDeploymentInstaller(strategyClient wrappers.InstallStrategyDeploymentInterface, owner ownerutil.Owner, previousStrategy Strategy) StrategyInstaller { +func NewStrategyDeploymentInstaller(strategyClient wrappers.InstallStrategyDeploymentInterface, templateAnnotations map[string]string, owner ownerutil.Owner, previousStrategy Strategy) StrategyInstaller { return &StrategyDeploymentInstaller{ - strategyClient: strategyClient, - owner: owner, - previousStrategy: previousStrategy, + strategyClient: strategyClient, + owner: owner, + previousStrategy: previousStrategy, + templateAnnotations: templateAnnotations, } } -func (i *StrategyDeploymentInstaller) installPermissions(perms []StrategyDeploymentPermissions) error { - for _, permission := range perms { - // create role - role := &rbac.Role{ - Rules: permission.Rules, - } - ownerutil.AddNonBlockingOwner(role, i.owner) - role.SetGenerateName(fmt.Sprintf("%s-role-", i.owner.GetName())) - createdRole, err := i.strategyClient.CreateRole(role) - if err != nil { - return err - } - - // create serviceaccount if necessary - serviceAccount := &corev1.ServiceAccount{} - serviceAccount.SetName(permission.ServiceAccountName) - // EnsureServiceAccount verifies/creates ownerreferences so we don't add them here - serviceAccount, err = i.strategyClient.EnsureServiceAccount(serviceAccount, i.owner) - if err != nil { - return err - } - - // create rolebinding - roleBinding := &rbac.RoleBinding{ - RoleRef: rbac.RoleRef{ - Kind: "Role", - Name: createdRole.GetName(), - APIGroup: rbac.GroupName}, - Subjects: []rbac.Subject{{ - Kind: "ServiceAccount", - Name: permission.ServiceAccountName, - Namespace: i.owner.GetNamespace(), - }}, - } - ownerutil.AddNonBlockingOwner(roleBinding, i.owner) - roleBinding.SetGenerateName(fmt.Sprintf("%s-%s-rolebinding-", createdRole.Name, serviceAccount.Name)) - - if _, err := i.strategyClient.CreateRoleBinding(roleBinding); err != nil { - return err - } - } - return nil -} - func (i *StrategyDeploymentInstaller) installDeployments(deps []StrategyDeploymentSpec) error { for _, d := range deps { - // Create or Update Deployment dep := &appsv1.Deployment{Spec: d.Spec} dep.SetName(d.Name) dep.SetNamespace(i.owner.GetNamespace()) + + // Merge annotations (to avoid losing info from pod template) + annotations := map[string]string{} + for k, v := range i.templateAnnotations { + annotations[k] = v + } + for k, v := range dep.Spec.Template.GetAnnotations() { + annotations[k] = v + } + dep.Spec.Template.SetAnnotations(annotations) + ownerutil.AddNonBlockingOwner(dep, i.owner) - if dep.Labels == nil { - dep.SetLabels(map[string]string{}) + if err := ownerutil.AddOwnerLabels(dep, i.owner); err != nil { + return err } - dep.Labels["alm-owner-name"] = i.owner.GetName() - dep.Labels["alm-owner-namespace"] = i.owner.GetNamespace() if _, err := i.strategyClient.CreateOrUpdateDeployment(dep); err != nil { return err } @@ -144,10 +109,6 @@ func (i *StrategyDeploymentInstaller) Install(s Strategy) error { return fmt.Errorf("attempted to install %s strategy with deployment installer", strategy.GetStrategyName()) } - if err := i.installPermissions(strategy.Permissions); err != nil { - return err - } - if err := i.installDeployments(strategy.DeploymentSpecs); err != nil { return err } @@ -170,13 +131,6 @@ func (i *StrategyDeploymentInstaller) CheckInstalled(s Strategy) (installed bool return false, StrategyError{Reason: StrategyErrReasonInvalidStrategy, Message: fmt.Sprintf("attempted to check %s strategy with deployment installer", strategy.GetStrategyName())} } - // Check service accounts - for _, perm := range strategy.Permissions { - if err := i.checkForServiceAccount(perm.ServiceAccountName); err != nil { - return false, err - } - } - // Check deployments if err := i.checkForDeployments(strategy.DeploymentSpecs); err != nil { return false, err @@ -184,19 +138,6 @@ func (i *StrategyDeploymentInstaller) CheckInstalled(s Strategy) (installed bool return true, nil } -func (i *StrategyDeploymentInstaller) checkForServiceAccount(serviceAccountName string) error { - if _, err := i.strategyClient.GetServiceAccountByName(serviceAccountName); err != nil { - if apierrors.IsNotFound(err) { - log.Debugf("service account not found: %s", serviceAccountName) - return StrategyError{Reason: StrategyErrReasonComponentMissing, Message: fmt.Sprintf("service account not found: %s", serviceAccountName)} - } - log.Debugf("error querying for %s: %s", serviceAccountName, err) - return StrategyError{Reason: StrategyErrReasonComponentMissing, Message: fmt.Sprintf("error querying for %s: %s", serviceAccountName, err)} - } - // TODO: use a SelfSubjectRulesReview (or a sync version) to verify ServiceAccount has correct access - return nil -} - func (i *StrategyDeploymentInstaller) checkForDeployments(deploymentSpecs []StrategyDeploymentSpec) error { var depNames []string for _, dep := range deploymentSpecs { @@ -227,6 +168,16 @@ func (i *StrategyDeploymentInstaller) checkForDeployments(deploymentSpecs []Stra if !ready { return StrategyError{Reason: StrategyErrReasonWaiting, Message: fmt.Sprintf("waiting for deployment %s to become ready: %s", dep.Name, reason)} } + + // check annotations + if len(i.templateAnnotations) > 0 && dep.Spec.Template.Annotations == nil { + return StrategyError{Reason: StrategyErrReasonAnnotationsMissing, Message: fmt.Sprintf("no annotations found on deployment")} + } + for key, value := range i.templateAnnotations { + if dep.Spec.Template.Annotations[key] != value { + return StrategyError{Reason: StrategyErrReasonAnnotationsMissing, Message: fmt.Sprintf("annotations on deployment don't match. couldn't find %s: %s", key, value)} + } + } } return nil } diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install/errors.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install/errors.go index 7eabd0cda7..47a0ae4411 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install/errors.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install/errors.go @@ -3,11 +3,12 @@ package install import "fmt" const ( - StrategyErrReasonComponentMissing = "ComponentMissing" - StrategyErrReasonWaiting = "Waiting" - StrategyErrReasonInvalidStrategy = "InvalidStrategy" - StrategyErrReasonTimeout = "Timeout" - StrategyErrReasonUnknown = "Unknown" + StrategyErrReasonComponentMissing = "ComponentMissing" + StrategyErrReasonAnnotationsMissing = "AnnotationsMissing" + StrategyErrReasonWaiting = "Waiting" + StrategyErrReasonInvalidStrategy = "InvalidStrategy" + StrategyErrReasonTimeout = "Timeout" + StrategyErrReasonUnknown = "Unknown" ) // unrecoverableErrors are the set of errors that mean we can't recover an install strategy diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install/resolver.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install/resolver.go index 3f090a5d8f..fcbac9ac16 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install/resolver.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install/resolver.go @@ -10,6 +10,7 @@ import ( "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" "github.com/operator-framework/operator-lifecycle-manager/pkg/api/wrappers" "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient" + "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister" "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil" ) @@ -24,7 +25,7 @@ type StrategyInstaller interface { type StrategyResolverInterface interface { UnmarshalStrategy(s v1alpha1.NamedInstallStrategy) (strategy Strategy, err error) - InstallerForStrategy(strategyName string, opClient operatorclient.ClientInterface, owner ownerutil.Owner, previousStrategy Strategy) StrategyInstaller + InstallerForStrategy(strategyName string, opClient operatorclient.ClientInterface, opLister operatorlister.OperatorLister, owner ownerutil.Owner, annotations map[string]string, previousStrategy Strategy) StrategyInstaller } type StrategyResolver struct{} @@ -42,11 +43,11 @@ func (r *StrategyResolver) UnmarshalStrategy(s v1alpha1.NamedInstallStrategy) (s return } -func (r *StrategyResolver) InstallerForStrategy(strategyName string, opClient operatorclient.ClientInterface, owner ownerutil.Owner, previousStrategy Strategy) StrategyInstaller { +func (r *StrategyResolver) InstallerForStrategy(strategyName string, opClient operatorclient.ClientInterface, opLister operatorlister.OperatorLister, owner ownerutil.Owner, annotations map[string]string, previousStrategy Strategy) StrategyInstaller { switch strategyName { case InstallStrategyNameDeployment: - strategyClient := wrappers.NewInstallStrategyDeploymentClient(opClient, owner.GetNamespace()) - return NewStrategyDeploymentInstaller(strategyClient, owner, previousStrategy) + strategyClient := wrappers.NewInstallStrategyDeploymentClient(opClient, opLister, owner.GetNamespace()) + return NewStrategyDeploymentInstaller(strategyClient, annotations, owner, previousStrategy) } // Insurance against these functions being called incorrectly (unmarshal strategy will return a valid strategy name) diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install/rule_checker.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install/rule_checker.go new file mode 100644 index 0000000000..7bc671a1cf --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install/rule_checker.go @@ -0,0 +1,154 @@ +package install + +import ( + "fmt" + + corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apiserver/pkg/authorization/authorizer" + crbacv1 "k8s.io/client-go/listers/rbac/v1" + rbacauthorizer "k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac" + + "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil" +) + +// RuleChecker is used to verify whether PolicyRules are satisfied by existing Roles or ClusterRoles +type RuleChecker interface { + // RuleSatisfied determines whether a PolicyRule is satisfied for a ServiceAccount + // by existing Roles and ClusterRoles + RuleSatisfied(sa *corev1.ServiceAccount, namespace string, rule rbacv1.PolicyRule) (bool, error) +} + +// CSVRuleChecker determines whether a PolicyRule is satisfied for a ServiceAccount +// by existing Roles and ClusterRoles +type CSVRuleChecker struct { + roleLister crbacv1.RoleLister + roleBindingLister crbacv1.RoleBindingLister + clusterRoleLister crbacv1.ClusterRoleLister + clusterRoleBindingLister crbacv1.ClusterRoleBindingLister + csv *v1alpha1.ClusterServiceVersion +} + +// NewCSVRuleChecker returns a pointer to a new CSVRuleChecker +func NewCSVRuleChecker(roleLister crbacv1.RoleLister, roleBindingLister crbacv1.RoleBindingLister, clusterRoleLister crbacv1.ClusterRoleLister, clusterRoleBindingLister crbacv1.ClusterRoleBindingLister, csv *v1alpha1.ClusterServiceVersion) *CSVRuleChecker { + return &CSVRuleChecker{ + roleLister: roleLister, + roleBindingLister: roleBindingLister, + clusterRoleLister: clusterRoleLister, + clusterRoleBindingLister: clusterRoleBindingLister, + csv: csv.DeepCopy(), + } +} + +// RuleSatisfied returns true if a ServiceAccount is authorized to perform all actions described by a PolicyRule in a namespace +func (c *CSVRuleChecker) RuleSatisfied(sa *corev1.ServiceAccount, namespace string, rule rbacv1.PolicyRule) (bool, error) { + // check if the rule is valid + err := ruleValid(rule) + if err != nil { + return false, fmt.Errorf("rule invalid: %s", err.Error()) + } + + // get attributes set for the given Role and ServiceAccount + user := toDefaultInfo(sa) + attributesSet := toAttributesSet(user, namespace, rule) + + // create a new RBACAuthorizer + rbacAuthorizer := rbacauthorizer.New(c, c, c, c) + + // ensure all attributes are authorized + for _, attributes := range attributesSet { + decision, _, err := rbacAuthorizer.Authorize(attributes) + if err != nil { + return false, err + } + + if decision == authorizer.DecisionDeny || decision == authorizer.DecisionNoOpinion { + return false, nil + } + + } + + return true, nil +} + +func (c *CSVRuleChecker) GetRole(namespace, name string) (*rbacv1.Role, error) { + // get the Role + role, err := c.roleLister.Roles(namespace).Get(name) + if err != nil { + return nil, err + } + + // check if the Role has an OwnerConflict with the client's CSV + if role != nil && ownerutil.HasOwnerConflict(c.csv, role.GetOwnerReferences()) { + return &rbacv1.Role{}, nil + } + + return role, nil +} + +func (c *CSVRuleChecker) ListRoleBindings(namespace string) ([]*rbacv1.RoleBinding, error) { + // get all RoleBindings + rbList, err := c.roleBindingLister.RoleBindings(namespace).List(labels.Everything()) + if err != nil { + return nil, err + } + + // filter based on OwnerReferences + var filtered []*rbacv1.RoleBinding + for _, rb := range rbList { + if !ownerutil.HasOwnerConflict(c.csv, rb.GetOwnerReferences()) { + filtered = append(filtered, rb) + } + } + + return filtered, nil +} + +func (c *CSVRuleChecker) GetClusterRole(name string) (*rbacv1.ClusterRole, error) { + // get the ClusterRole + clusterRole, err := c.clusterRoleLister.Get(name) + if err != nil { + return nil, err + } + + // check if the ClusterRole has an OwnerConflict with the client's CSV + if clusterRole != nil && ownerutil.HasOwnerConflict(c.csv, clusterRole.GetOwnerReferences()) { + return &rbacv1.ClusterRole{}, nil + } + + return clusterRole, nil +} + +func (c *CSVRuleChecker) ListClusterRoleBindings() ([]*rbacv1.ClusterRoleBinding, error) { + // get all RoleBindings + crbList, err := c.clusterRoleBindingLister.List(labels.Everything()) + if err != nil { + return nil, err + } + + // filter based on OwnerReferences + var filtered []*rbacv1.ClusterRoleBinding + for _, crb := range crbList { + if !ownerutil.HasOwnerConflict(c.csv, crb.GetOwnerReferences()) { + filtered = append(filtered, crb) + } + } + + return filtered, nil +} + +// ruleValid returns an error if the given PolicyRule is not valid (resource and nonresource attributes defined) +func ruleValid(rule rbacv1.PolicyRule) error { + if len(rule.Verbs) == 0 { + return fmt.Errorf("policy rule must have at least one verb") + } + + resourceCount := len(rule.APIGroups) + len(rule.Resources) + len(rule.ResourceNames) + if resourceCount > 0 && len(rule.NonResourceURLs) > 0 { + return fmt.Errorf("rule cannot apply to both regular resources and non-resource URLs") + } + + return nil +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/catalog/operator.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/catalog/operator.go index a432772f8f..6d90dcda05 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/catalog/operator.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/catalog/operator.go @@ -1,20 +1,27 @@ package catalog import ( + "context" "encoding/json" "errors" "fmt" - "sync" "time" - olmerrors "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/errors" - log "github.com/sirupsen/logrus" - "k8s.io/api/core/v1" + "github.com/operator-framework/operator-registry/pkg/api/grpc_health_v1" + registryclient "github.com/operator-framework/operator-registry/pkg/client" + errorwrap "github.com/pkg/errors" + "github.com/sirupsen/logrus" + "google.golang.org/grpc/connectivity" + corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" v1beta1ext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" 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" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/client-go/informers" "k8s.io/client-go/tools/cache" "k8s.io/client-go/util/workqueue" @@ -22,89 +29,114 @@ import ( "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client" "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned" "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions" - "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry" + olmerrors "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/errors" + "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/reconciler" "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver" + "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister" "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil" "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/queueinformer" + "github.com/operator-framework/operator-lifecycle-manager/pkg/metrics" ) const ( - crdKind = "CustomResourceDefinition" - secretKind = "Secret" - clusterRoleKind = "ClusterRole" + crdKind = "CustomResourceDefinition" + secretKind = "Secret" + clusterRoleKind = "ClusterRole" + clusterRoleBindingKind = "ClusterRoleBinding" + serviceAccountKind = "ServiceAccount" + serviceKind = "Service" + roleKind = "Role" + roleBindingKind = "RoleBinding" + generatedByKey = "olm.generated-by" ) -//for test stubbing and for ensuring standardization of timezones to UTC +// for test stubbing and for ensuring standardization of timezones to UTC var timeNow = func() metav1.Time { return metav1.NewTime(time.Now().UTC()) } // Operator represents a Kubernetes operator that executes InstallPlans by // resolving dependencies in a catalog. type Operator struct { *queueinformer.Operator - client versioned.Interface - namespace string - sources map[registry.ResourceKey]registry.Source - sourcesLock sync.RWMutex - sourcesLastUpdate metav1.Time - dependencyResolver resolver.DependencyResolver - subQueue workqueue.RateLimitingInterface + client versioned.Interface + lister operatorlister.OperatorLister + namespace string + sources map[resolver.CatalogKey]resolver.SourceRef + sourcesLock sync.RWMutex + sourcesLastUpdate metav1.Time + resolver resolver.Resolver + subQueue workqueue.RateLimitingInterface + catSrcQueueSet *queueinformer.ResourceQueueSet + namespaceResolveQueue workqueue.RateLimitingInterface + reconciler reconciler.ReconcilerFactory } // NewOperator creates a new Catalog Operator. -func NewOperator(kubeconfigPath string, wakeupInterval time.Duration, operatorNamespace string, watchedNamespaces ...string) (*Operator, error) { +func NewOperator(kubeconfigPath string, logger *logrus.Logger, wakeupInterval time.Duration, configmapRegistryImage, operatorNamespace string, watchedNamespaces ...string) (*Operator, error) { // Default to watching all namespaces. if watchedNamespaces == nil { watchedNamespaces = []string{metav1.NamespaceAll} } - // Create a new client for ALM types (CRs) + // Create a new client for OLM types (CRs) crClient, err := client.NewClient(kubeconfigPath) if err != nil { return nil, err } + // Create an OperatorLister + lister := operatorlister.NewLister() + // Create an informer for each watched namespace. ipSharedIndexInformers := []cache.SharedIndexInformer{} subSharedIndexInformers := []cache.SharedIndexInformer{} + csvSharedIndexInformers := []cache.SharedIndexInformer{} for _, namespace := range watchedNamespaces { nsInformerFactory := externalversions.NewSharedInformerFactoryWithOptions(crClient, wakeupInterval, externalversions.WithNamespace(namespace)) ipSharedIndexInformers = append(ipSharedIndexInformers, nsInformerFactory.Operators().V1alpha1().InstallPlans().Informer()) subSharedIndexInformers = append(subSharedIndexInformers, nsInformerFactory.Operators().V1alpha1().Subscriptions().Informer()) - } + csvSharedIndexInformers = append(csvSharedIndexInformers, nsInformerFactory.Operators().V1alpha1().ClusterServiceVersions().Informer()) - // Create an informer for each catalog namespace - catsrcSharedIndexInformers := []cache.SharedIndexInformer{} - for _, namespace := range []string{operatorNamespace} { - nsInformerFactory := externalversions.NewSharedInformerFactoryWithOptions(crClient, wakeupInterval, externalversions.WithNamespace(namespace)) - catsrcSharedIndexInformers = append(catsrcSharedIndexInformers, nsInformerFactory.Operators().V1alpha1().CatalogSources().Informer()) + // resolver needs subscription and csv listers + lister.OperatorsV1alpha1().RegisterSubscriptionLister(namespace, nsInformerFactory.Operators().V1alpha1().Subscriptions().Lister()) + lister.OperatorsV1alpha1().RegisterClusterServiceVersionLister(namespace, nsInformerFactory.Operators().V1alpha1().ClusterServiceVersions().Lister()) + lister.OperatorsV1alpha1().RegisterInstallPlanLister(namespace, nsInformerFactory.Operators().V1alpha1().InstallPlans().Lister()) } // Create a new queueinformer-based operator. - queueOperator, err := queueinformer.NewOperator(kubeconfigPath) + queueOperator, err := queueinformer.NewOperator(kubeconfigPath, logger) if err != nil { return nil, err } // Allocate the new instance of an Operator. op := &Operator{ - Operator: queueOperator, - client: crClient, - namespace: operatorNamespace, - sources: make(map[registry.ResourceKey]registry.Source), - dependencyResolver: &resolver.MultiSourceResolver{}, - } - - // Register CatalogSource informers. - catsrcQueue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "catalogsources") - catsrcQueueInformer := queueinformer.New( - catsrcQueue, - catsrcSharedIndexInformers, - op.syncCatalogSources, - nil, - "catsrc", - ) - for _, informer := range catsrcQueueInformer { - op.RegisterQueueInformer(informer) + Operator: queueOperator, + catSrcQueueSet: queueinformer.NewEmptyResourceQueueSet(), + client: crClient, + lister: lister, + namespace: operatorNamespace, + sources: make(map[resolver.CatalogKey]resolver.SourceRef), + resolver: resolver.NewOperatorsV1alpha1Resolver(lister), + } + + // Create an informer for each catalog namespace + deleteCatSrc := &cache.ResourceEventHandlerFuncs{ + DeleteFunc: op.handleCatSrcDeletion, + } + for _, namespace := range watchedNamespaces { + nsInformerFactory := externalversions.NewSharedInformerFactoryWithOptions(crClient, wakeupInterval, externalversions.WithNamespace(namespace)) + catsrcInformer := nsInformerFactory.Operators().V1alpha1().CatalogSources() + + // Register queue and QueueInformer + var queueName string + if namespace == corev1.NamespaceAll { + queueName = "catsrc" + } else { + queueName = fmt.Sprintf("%s/catsrc", namespace) + } + catsrcQueue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), queueName) + op.RegisterQueueInformer(queueinformer.NewInformer(catsrcQueue, catsrcInformer.Informer(), op.syncCatalogSources, deleteCatSrc, queueName, metrics.NewMetricsCatalogSource(op.client), logger)) + op.catSrcQueueSet.Set(namespace, catsrcQueue) } // Register InstallPlan informers. @@ -115,6 +147,8 @@ func NewOperator(kubeconfigPath string, wakeupInterval time.Duration, operatorNa op.syncInstallPlans, nil, "installplan", + metrics.NewMetricsInstallPlan(op.client), + logger, ) for _, informer := range ipQueueInformers { op.RegisterQueueInformer(informer) @@ -128,110 +162,718 @@ func NewOperator(kubeconfigPath string, wakeupInterval time.Duration, operatorNa op.syncSubscriptions, nil, "subscription", + metrics.NewMetricsSubscription(op.client), + logger, ) op.subQueue = subscriptionQueue for _, informer := range subscriptionQueueInformers { op.RegisterQueueInformer(informer) } + handleDelete := &cache.ResourceEventHandlerFuncs{ + DeleteFunc: op.handleDeletion, + } + // Set up informers for requeuing catalogs + for _, namespace := range watchedNamespaces { + roleQueue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "role") + roleBindingQueue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "rolebinding") + serviceAccountQueue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "serviceaccount") + serviceQueue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "service") + podQueue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "pod") + configmapQueue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "configmap") + + informerFactory := informers.NewSharedInformerFactoryWithOptions(op.OpClient.KubernetesInterface(), wakeupInterval, informers.WithNamespace(namespace)) + roleInformer := informerFactory.Rbac().V1().Roles() + roleBindingInformer := informerFactory.Rbac().V1().RoleBindings() + serviceAccountInformer := informerFactory.Core().V1().ServiceAccounts() + serviceInformer := informerFactory.Core().V1().Services() + podInformer := informerFactory.Core().V1().Pods() + configMapInformer := informerFactory.Core().V1().ConfigMaps() + + queueInformers := []*queueinformer.QueueInformer{ + queueinformer.NewInformer(roleQueue, roleInformer.Informer(), op.syncObject, handleDelete, "role", metrics.NewMetricsNil(), logger), + queueinformer.NewInformer(roleBindingQueue, roleBindingInformer.Informer(), op.syncObject, handleDelete, "rolebinding", metrics.NewMetricsNil(), logger), + queueinformer.NewInformer(serviceAccountQueue, serviceAccountInformer.Informer(), op.syncObject, handleDelete, "serviceaccount", metrics.NewMetricsNil(), logger), + queueinformer.NewInformer(serviceQueue, serviceInformer.Informer(), op.syncObject, handleDelete, "service", metrics.NewMetricsNil(), logger), + queueinformer.NewInformer(podQueue, podInformer.Informer(), op.syncObject, handleDelete, "pod", metrics.NewMetricsNil(), logger), + queueinformer.NewInformer(configmapQueue, configMapInformer.Informer(), op.syncObject, handleDelete, "configmap", metrics.NewMetricsNil(), logger), + } + for _, q := range queueInformers { + op.RegisterQueueInformer(q) + } + + op.lister.RbacV1().RegisterRoleLister(namespace, roleInformer.Lister()) + op.lister.RbacV1().RegisterRoleBindingLister(namespace, roleBindingInformer.Lister()) + op.lister.CoreV1().RegisterServiceAccountLister(namespace, serviceAccountInformer.Lister()) + op.lister.CoreV1().RegisterServiceLister(namespace, serviceInformer.Lister()) + op.lister.CoreV1().RegisterPodLister(namespace, podInformer.Lister()) + op.lister.CoreV1().RegisterConfigMapLister(namespace, configMapInformer.Lister()) + } + op.reconciler = &reconciler.RegistryReconcilerFactory{ + ConfigMapServerImage: configmapRegistryImage, + OpClient: op.OpClient, + Lister: op.lister, + } + + // Namespace sync for resolving subscriptions + namespaceInformer := informers.NewSharedInformerFactory(op.OpClient.KubernetesInterface(), wakeupInterval).Core().V1().Namespaces() + resolvingNamespaceQueue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "resolver") + namespaceQueueInformer := queueinformer.NewInformer( + resolvingNamespaceQueue, + namespaceInformer.Informer(), + op.syncResolvingNamespace, + nil, + "resolver", + metrics.NewMetricsNil(), + logger, + ) + + op.RegisterQueueInformer(namespaceQueueInformer) + op.lister.CoreV1().RegisterNamespaceLister(namespaceInformer.Lister()) + op.namespaceResolveQueue = resolvingNamespaceQueue + + // Register CSV informers to fill cache + for _, informer := range csvSharedIndexInformers { + op.RegisterInformer(informer) + } + return op, nil } +func (o *Operator) syncObject(obj interface{}) (syncError error) { + // Assert as runtime.Object + runtimeObj, ok := obj.(runtime.Object) + if !ok { + syncError = errors.New("object sync: casting to runtime.Object failed") + o.Log.Warn(syncError.Error()) + return + } + + gvk := runtimeObj.GetObjectKind().GroupVersionKind() + logger := o.Log.WithFields(logrus.Fields{ + "group": gvk.Group, + "version": gvk.Version, + "kind": gvk.Kind, + }) + + // Assert as metav1.Object + metaObj, ok := obj.(metav1.Object) + if !ok { + syncError = errors.New("object sync: casting to metav1.Object failed") + logger.Warn(syncError.Error()) + return + } + logger = logger.WithFields(logrus.Fields{ + "name": metaObj.GetName(), + "namespace": metaObj.GetNamespace(), + }) + + if owner := ownerutil.GetOwnerByKind(metaObj, v1alpha1.CatalogSourceKind); owner != nil { + sourceKey := resolver.CatalogKey{Name: owner.Name, Namespace: metaObj.GetNamespace()} + func() { + o.sourcesLock.RLock() + defer o.sourcesLock.RUnlock() + if _, ok := o.sources[sourceKey]; ok { + logger.Debug("requeueing owner CatalogSource") + if err := o.catSrcQueueSet.Requeue(owner.Name, metaObj.GetNamespace()); err != nil { + logger.Warn(err.Error()) + } + } + }() + } + + return nil +} + +func (o *Operator) handleDeletion(obj interface{}) { + ownee, ok := obj.(metav1.Object) + if !ok { + tombstone, ok := obj.(cache.DeletedFinalStateUnknown) + if !ok { + utilruntime.HandleError(fmt.Errorf("Couldn't get object from tombstone %#v", obj)) + return + } + + ownee, ok = tombstone.Obj.(metav1.Object) + if !ok { + utilruntime.HandleError(fmt.Errorf("Tombstone contained object that is not a metav1 object %#v", obj)) + return + } + } + + if owner := ownerutil.GetOwnerByKind(ownee, v1alpha1.CatalogSourceKind); owner != nil { + if err := o.catSrcQueueSet.Requeue(owner.Name, ownee.GetNamespace()); err != nil { + o.Log.Warn(err.Error()) + } + } +} + +func (o *Operator) handleCatSrcDeletion(obj interface{}) { + catsrc, ok := obj.(metav1.Object) + if !ok { + if !ok { + tombstone, ok := obj.(cache.DeletedFinalStateUnknown) + if !ok { + utilruntime.HandleError(fmt.Errorf("Couldn't get object from tombstone %#v", obj)) + return + } + + catsrc, ok = tombstone.Obj.(metav1.Object) + if !ok { + utilruntime.HandleError(fmt.Errorf("Tombstone contained object that is not a Namespace %#v", obj)) + return + } + } + } + sourceKey := resolver.CatalogKey{Name: catsrc.GetName(), Namespace: catsrc.GetNamespace()} + func() { + o.sourcesLock.Lock() + defer o.sourcesLock.Unlock() + delete(o.sources, sourceKey) + }() + o.Log.WithField("source", sourceKey).Info("removed client for deleted catalogsource") + + if err := o.catSrcQueueSet.Remove(sourceKey.Name, sourceKey.Namespace); err != nil { + o.Log.WithError(err) + } +} + func (o *Operator) syncCatalogSources(obj interface{}) (syncError error) { catsrc, ok := obj.(*v1alpha1.CatalogSource) if !ok { - log.Debugf("wrong type: %#v", obj) + o.Log.Debugf("wrong type: %#v", obj) return fmt.Errorf("casting CatalogSource failed") } - // Get the catalog source's config map - configMap, err := o.OpClient.KubernetesInterface().CoreV1().ConfigMaps(catsrc.GetNamespace()).Get(catsrc.Spec.ConfigMap, metav1.GetOptions{}) - if err != nil { - return fmt.Errorf("failed to get catalog config map %s when updating status: %s", catsrc.Spec.ConfigMap, err) + logger := o.Log.WithFields(logrus.Fields{ + "source": catsrc.GetName(), + "id": queueinformer.NewLoopID(), + }) + logger.Debug("syncing catsrc") + out := catsrc.DeepCopy() + sourceKey := resolver.CatalogKey{Name: catsrc.GetName(), Namespace: catsrc.GetNamespace()} + + if catsrc.Spec.SourceType == v1alpha1.SourceTypeInternal || catsrc.Spec.SourceType == v1alpha1.SourceTypeConfigmap { + logger.Debug("checking catsrc configmap state") + + // Get the catalog source's config map + configMap, err := o.lister.CoreV1().ConfigMapLister().ConfigMaps(catsrc.GetNamespace()).Get(catsrc.Spec.ConfigMap) + if err != nil { + return fmt.Errorf("failed to get catalog config map %s: %s", catsrc.Spec.ConfigMap, err) + } + + if wasOwned := ownerutil.EnsureOwner(configMap, catsrc); !wasOwned { + configMap, err = o.OpClient.KubernetesInterface().CoreV1().ConfigMaps(configMap.GetNamespace()).Update(configMap) + if err != nil { + return fmt.Errorf("unable to write owner onto catalog source configmap") + } + logger.Debug("adopted configmap") + } + + if catsrc.Status.ConfigMapResource == nil || catsrc.Status.ConfigMapResource.UID != configMap.GetUID() || catsrc.Status.ConfigMapResource.ResourceVersion != configMap.GetResourceVersion() { + logger.Debug("updating catsrc configmap state") + // configmap ref nonexistent or updated, write out the new configmap ref to status and exit + out.Status.ConfigMapResource = &v1alpha1.ConfigMapResourceReference{ + Name: configMap.GetName(), + Namespace: configMap.GetNamespace(), + UID: configMap.GetUID(), + ResourceVersion: configMap.GetResourceVersion(), + } + out.Status.LastSync = timeNow() + if _, err = o.client.OperatorsV1alpha1().CatalogSources(out.GetNamespace()).UpdateStatus(out); err != nil { + return err + } + + o.sourcesLastUpdate = timeNow() + + return nil + } + + logger.Debug("catsrc configmap state good, checking registry pod") + } + + reconciler := o.reconciler.ReconcilerForSource(catsrc) + if reconciler == nil { + // TODO: Add failure status on catalogsource and remove from sources + return fmt.Errorf("no reconciler for source type %s", catsrc.Spec.SourceType) } - o.sourcesLock.Lock() - defer o.sourcesLock.Unlock() - sourceKey := registry.ResourceKey{Name: catsrc.GetName(), Namespace: catsrc.GetNamespace()} - _, ok = o.sources[sourceKey] + // if registry pod hasn't been created or hasn't been updated since the last configmap update, recreate it + if catsrc.Status.RegistryServiceStatus == nil || catsrc.Status.RegistryServiceStatus.CreatedAt.Before(&catsrc.Status.LastSync) { + logger.Debug("registry server scheduled recheck") + + if err := reconciler.EnsureRegistryServer(out); err != nil { + logger.WithError(err).Warn("couldn't ensure registry server") + return err + } + logger.Debug("ensured registry server") + + out.Status.RegistryServiceStatus.CreatedAt = timeNow() + out.Status.LastSync = timeNow() + + logger.Debug("updating catsrc status") + // update status + if _, err := o.client.OperatorsV1alpha1().CatalogSources(out.GetNamespace()).UpdateStatus(out); err != nil { + return err + } + + o.sourcesLastUpdate = timeNow() + logger.Debug("registry server recreated") - // Check for catalog source changes - if ok && catsrc.Status.ConfigMapResource != nil && catsrc.Status.ConfigMapResource.Name == configMap.GetName() && catsrc.Status.ConfigMapResource.ResourceVersion == configMap.GetResourceVersion() { return nil } + logger.Debug("registry state good") + + // update operator's view of sources + sourcesUpdated := false + func() { + o.sourcesLock.Lock() + defer o.sourcesLock.Unlock() + address := catsrc.Address() + currentSource, ok := o.sources[sourceKey] + logger = logger.WithField("currentSource", sourceKey) + if !ok || currentSource.Address != address || catsrc.Status.LastSync.After(currentSource.LastConnect.Time) { + logger.Info("building connection to registry") + client, err := registryclient.NewClient(address) + if err != nil { + logger.WithError(err).Warn("couldn't connect to registry") + } + sourceRef := resolver.SourceRef{ + Address: address, + Client: client, + LastConnect: timeNow(), + LastHealthy: metav1.Time{}, // haven't detected healthy yet + } + o.sources[sourceKey] = sourceRef + currentSource = sourceRef + sourcesUpdated = true + } + if currentSource.LastHealthy.IsZero() { + logger.Info("client hasn't yet become healthy, attempt a health check") + client, ok := currentSource.Client.(*registryclient.Client) + if !ok { + logger.WithField("client", currentSource.Client).Warn("unexpected client") + return + } + res, err := client.Health.Check(context.TODO(), &grpc_health_v1.HealthCheckRequest{Service: "Registry"}) + if err != nil { + logger.WithError(err).Debug("error checking health") + if client.Conn.GetState() == connectivity.TransientFailure { + logger.Debug("wait for state to change") + ctx, _ := context.WithTimeout(context.TODO(), 1*time.Second) + if !client.Conn.WaitForStateChange(ctx, connectivity.TransientFailure) { + logger.Debug("state didn't change, trigger reconnect. this may happen when cached dns is wrong.") + delete(o.sources, sourceKey) + if err := o.catSrcQueueSet.Requeue(sourceKey.Name, sourceKey.Namespace); err != nil { + logger.WithError(err).Debug("error requeueing") + } + return + } + } + return + } + if res.Status != grpc_health_v1.HealthCheckResponse_SERVING { + logger.WithField("status", res.Status.String()).Debug("source not healthy") + return + } + currentSource.LastHealthy = timeNow() + o.sources[sourceKey] = currentSource + sourcesUpdated = true + } + }() - // Update status subresource - out := catsrc.DeepCopy() - out.Status.ConfigMapResource = &v1alpha1.ConfigMapResourceReference{ - Name: configMap.GetName(), - Namespace: configMap.GetNamespace(), - UID: configMap.GetUID(), - ResourceVersion: configMap.GetResourceVersion(), + if !sourcesUpdated { + return nil } + + // record that we've done work here onto the status out.Status.LastSync = timeNow() + if _, err := o.client.OperatorsV1alpha1().CatalogSources(out.GetNamespace()).UpdateStatus(out); err != nil { + return err + } - _, err = o.client.OperatorsV1alpha1().CatalogSources(out.GetNamespace()).UpdateStatus(out) + // Trigger a resolve, will pick up any subscriptions that depend on the catalog + o.resolveNamespace(out.GetNamespace()) + + return nil +} + +func (o *Operator) syncDependentSubscriptions(logger *logrus.Entry, catalogSource, catalogSourceNamespace string) { + subs, err := o.lister.OperatorsV1alpha1().SubscriptionLister().List(labels.Everything()) if err != nil { - return fmt.Errorf("failed to update catalog source %s status: %s", out.GetName(), err) + logger.Warnf("could not list Subscriptions") + return } - // Create a new in-mem registry - src, err := registry.NewInMemoryFromConfigMap(o.OpClient, out.GetNamespace(), out.Spec.ConfigMap) + for _, sub := range subs { + logger = logger.WithFields(logrus.Fields{ + "subscriptionCatalogSource": sub.Spec.CatalogSource, + "subscriptionCatalogNamespace": sub.Spec.CatalogSourceNamespace, + "subscription": sub.GetName(), + }) + catalogNamespace := sub.Spec.CatalogSourceNamespace + if catalogNamespace == "" { + catalogNamespace = o.namespace + } + if sub.Spec.CatalogSource == catalogSource && catalogNamespace == catalogSourceNamespace { + logger.Debug("requeueing subscription because catalog changed") + o.requeueSubscription(sub.GetName(), sub.GetNamespace()) + } + } +} + +func (o *Operator) syncResolvingNamespace(obj interface{}) error { + ns, ok := obj.(*corev1.Namespace) + if !ok { + o.Log.Debugf("wrong type: %#v", obj) + return fmt.Errorf("casting Namespace failed") + } + namespace := ns.GetName() + + logger := o.Log.WithFields(logrus.Fields{ + "namespace": namespace, + "id": queueinformer.NewLoopID(), + }) + + // get the set of sources that should be used for resolution and best-effort get their connections working + logger.Debug("resolving sources") + resolverSources := o.ensureResolverSources(logger, namespace) + querier := resolver.NewNamespaceSourceQuerier(resolverSources) + + logger.Debug("checking if subscriptions need update") + + subs, err := o.lister.OperatorsV1alpha1().SubscriptionLister().Subscriptions(namespace).List(labels.Everything()) if err != nil { - return fmt.Errorf("failed to create catalog source from ConfigMap %s: %s", out.Spec.ConfigMap, err) + logger.WithError(err).Debug("couldn't list subscriptions") + return err } - // Update sources map - o.sources[sourceKey] = src - o.sourcesLastUpdate = timeNow() + // TODO: parallel + subscriptionUpdated := false + for _, sub := range subs { + logger := logger.WithFields(logrus.Fields{ + "sub": sub.GetName(), + "source": sub.Spec.CatalogSource, + "pkg": sub.Spec.Package, + "channel": sub.Spec.Channel, + }) + + // ensure the installplan reference is correct + sub, changedIp, err := o.ensureSubscriptionInstallPlanState(logger, sub) + if err != nil { + return err + } + subscriptionUpdated = subscriptionUpdated || changedIp + + // record the current state of the desired corresponding CSV in the status. no-op if we don't know the csv yet. + sub, changedCSV, err := o.ensureSubscriptionCSVState(logger, sub, querier) + if err != nil { + return err + } + + subscriptionUpdated = subscriptionUpdated || changedCSV + } + if subscriptionUpdated { + logger.Debug("subscriptions were updated, wait for a new resolution") + return nil + } + + shouldUpdate := false + for _, sub := range subs { + shouldUpdate = shouldUpdate || !o.nothingToUpdate(logger, sub) + } + if !shouldUpdate { + logger.Debug("all subscriptions up to date") + return nil + } + + logger.Debug("resolving subscriptions in namespace") + + // resolve a set of steps to apply to a cluster, a set of subscriptions to create/update, and any errors + steps, updatedSubs, err := o.resolver.ResolveSteps(namespace, querier) + if err != nil { + return err + } + + // create installplan if anything updated + if len(updatedSubs) > 0 { + logger.Debug("resolution caused subscription changes, creating installplan") + // any subscription in the namespace with manual approval will force generated installplans to be manual + // TODO: this is an odd artifact of the older resolver, and will probably confuse users. approval mode could be on the operatorgroup? + installPlanApproval := v1alpha1.ApprovalAutomatic + for _, sub := range subs { + if sub.Spec.InstallPlanApproval == v1alpha1.ApprovalManual { + installPlanApproval = v1alpha1.ApprovalManual + break + } + } + + installPlanReference, err := o.ensureInstallPlan(logger, namespace, subs, installPlanApproval, steps) + if err != nil { + logger.WithError(err).Debug("error ensuring installplan") + return err + } + if err := o.updateSubscriptionStatus(namespace, updatedSubs, installPlanReference); err != nil { + logger.WithError(err).Debug("error ensuring subscription installplan state") + return err + } + return nil + } return nil } -func (o *Operator) syncSubscriptions(obj interface{}) (syncError error) { +func (o *Operator) syncSubscriptions(obj interface{}) error { sub, ok := obj.(*v1alpha1.Subscription) if !ok { - log.Debugf("wrong type: %#v", obj) + o.Log.Debugf("wrong type: %#v", obj) return fmt.Errorf("casting Subscription failed") } - logger := log.WithFields(log.Fields{ - "sub": sub.GetName(), - "namespace": sub.GetNamespace(), - "source": sub.Spec.CatalogSource, - "pkg": sub.Spec.Package, - "channel": sub.Spec.Channel, - }) + o.resolveNamespace(sub.GetNamespace()) - logger.Infof("syncing") + return nil +} - var updatedSub *v1alpha1.Subscription - updatedSub, syncError = o.syncSubscription(sub) +func (o *Operator) resolveNamespace(namespace string) { + o.namespaceResolveQueue.AddRateLimited(namespace) +} - if updatedSub == nil || updatedSub.Status.State == sub.Status.State { - return +func (o *Operator) ensureResolverSources(logger *logrus.Entry, namespace string) map[resolver.CatalogKey]registryclient.Interface { + // TODO: record connection status onto an object + resolverSources := make(map[resolver.CatalogKey]registryclient.Interface, 0) + func() { + o.sourcesLock.RLock() + defer o.sourcesLock.RUnlock() + for k, ref := range o.sources { + if ref.LastHealthy.IsZero() { + logger = logger.WithField("source", k) + logger.Debug("omitting source, hasn't yet become healthy") + if err := o.catSrcQueueSet.Requeue(k.Name, k.Namespace); err != nil { + logger.Warn("error requeueing") + } + continue + } + // only resolve in namespace local + global catalogs + if k.Namespace == namespace || k.Namespace == o.namespace { + resolverSources[k] = ref.Client + } + } + }() + + for k, s := range resolverSources { + client, ok := s.(*registryclient.Client) + if !ok { + logger.Warn("unexpected client") + continue + } + + logger = logger.WithField("resolverSource", k) + logger.WithField("clientState", client.Conn.GetState()).Debug("source") + if client.Conn.GetState() == connectivity.TransientFailure { + logger.WithField("clientState", client.Conn.GetState()).Debug("waiting for connection") + ctx, _ := context.WithTimeout(context.TODO(), 2*time.Second) + changed := client.Conn.WaitForStateChange(ctx, connectivity.TransientFailure) + if !changed { + logger.WithField("clientState", client.Conn.GetState()).Debug("source in transient failure and didn't recover") + delete(resolverSources, k) + } else { + logger.WithField("clientState", client.Conn.GetState()).Debug("connection re-established") + } + } } - if syncError != nil { - logger = logger.WithField("syncError", syncError) + return resolverSources +} + +func (o *Operator) nothingToUpdate(logger *logrus.Entry, sub *v1alpha1.Subscription) bool { + // Only sync if catalog has been updated since last sync time + if o.sourcesLastUpdate.Before(&sub.Status.LastUpdated) && sub.Status.State != v1alpha1.SubscriptionStateUpgradeAvailable { + logger.Debugf("skipping update: no new updates to catalog since last sync at %s", sub.Status.LastUpdated.String()) + return true + } + if sub.Status.Install != nil && sub.Status.State == v1alpha1.SubscriptionStateUpgradePending { + logger.Debugf("skipping update: installplan already created") + return true + } + return false +} + +func (o *Operator) ensureSubscriptionInstallPlanState(logger *logrus.Entry, sub *v1alpha1.Subscription) (*v1alpha1.Subscription, bool, error) { + if sub.Status.Install != nil { + return sub, false, nil + } + + logger.Debug("checking for existing installplan") + + // check if there's an installplan that created this subscription (only if it doesn't have a reference yet) + // this indicates it was newly resolved by another operator, and we should reference that installplan in the status + ipName, ok := sub.GetAnnotations()[generatedByKey] + if !ok { + return sub, false, nil + } + + ip, err := o.lister.OperatorsV1alpha1().InstallPlanLister().InstallPlans(sub.GetNamespace()).Get(ipName) + if err != nil { + logger.WithField("installplan", ipName).Warn("unable to get installplan from cache") + return nil, false, err + } + logger.WithField("installplan", ipName).Debug("found installplan that generated subscription") + + out := sub.DeepCopy() + out.Status.Install = o.referenceForInstallPlan(ip) + out.Status.State = v1alpha1.SubscriptionStateUpgradePending + updated, err := o.client.OperatorsV1alpha1().Subscriptions(sub.GetNamespace()).UpdateStatus(out) + if err != nil { + return nil, false, err + } + + return updated, true, nil +} + +func (o *Operator) ensureSubscriptionCSVState(logger *logrus.Entry, sub *v1alpha1.Subscription, querier resolver.SourceQuerier) (*v1alpha1.Subscription, bool, error) { + if sub.Status.CurrentCSV == "" { + return sub, false, nil } - updatedSub.Status.LastUpdated = timeNow() + _, err := o.client.OperatorsV1alpha1().ClusterServiceVersions(sub.GetNamespace()).Get(sub.Status.CurrentCSV, metav1.GetOptions{}) + out := sub.DeepCopy() + if err != nil { + logger.WithError(err).WithField("currentCSV", sub.Status.CurrentCSV).Debug("error fetching csv listed in subscription status") + out.Status.State = v1alpha1.SubscriptionStateUpgradePending + } else { + // Check if an update is available for the current csv + if err := querier.Queryable(); err != nil { + return nil, false, err + } + bundle, _, _ := querier.FindReplacement(sub.Status.CurrentCSV, sub.Spec.Package, sub.Spec.Channel, resolver.CatalogKey{sub.Spec.CatalogSource, sub.Spec.CatalogSourceNamespace}) + if bundle != nil { + out.Status.State = v1alpha1.SubscriptionStateUpgradeAvailable + } else { + out.Status.State = v1alpha1.SubscriptionStateAtLatest + } + + out.Status.InstalledCSV = sub.Status.CurrentCSV + } + + if sub.Status.State == out.Status.State { + // The subscription status represents the cluster state + return sub, false, nil + } + out.Status.LastUpdated = timeNow() + // Update Subscription with status of transition. Log errors if we can't write them to the status. - if _, err := o.client.OperatorsV1alpha1().Subscriptions(updatedSub.GetNamespace()).UpdateStatus(updatedSub); err != nil { - logger = logger.WithField("updateError", err.Error()) - updateErr := errors.New("error updating Subscription status: " + err.Error()) - if syncError == nil { - logger.Info("error updating Subscription status") - return updateErr + if sub, err = o.client.OperatorsV1alpha1().Subscriptions(out.GetNamespace()).UpdateStatus(out); err != nil { + logger.WithError(err).Info("error updating subscription status") + return nil, false, fmt.Errorf("error updating Subscription status: " + err.Error()) + } + + // subscription status represents cluster state + return sub, true, nil +} + +func (o *Operator) updateSubscriptionStatus(namespace string, subs []*v1alpha1.Subscription, installPlanRef *v1alpha1.InstallPlanReference) error { + // TODO: parallel, sync waitgroup + var err error + for _, sub := range subs { + sub.Status.LastUpdated = timeNow() + if installPlanRef != nil { + sub.Status.Install = installPlanRef + sub.Status.State = v1alpha1.SubscriptionStateUpgradePending + } + if _, subErr := o.client.OperatorsV1alpha1().Subscriptions(namespace).UpdateStatus(sub); subErr != nil { + err = subErr } - logger.Info("error transitioning Subscription") - syncError = fmt.Errorf("error transitioning Subscription: %s and error updating Subscription status: %s", syncError, updateErr) + } + return err +} + +func (o *Operator) ensureInstallPlan(logger *logrus.Entry, namespace string, subs []*v1alpha1.Subscription, installPlanApproval v1alpha1.Approval, steps []*v1alpha1.Step) (*v1alpha1.InstallPlanReference, error) { + if len(steps) == 0 { + return nil, nil } - return + // Check if any existing installplans are creating the same resources + installPlans, err := o.lister.OperatorsV1alpha1().InstallPlanLister().InstallPlans(namespace).List(labels.Everything()) + if err != nil { + return nil, err + } + + for _, installPlan := range installPlans { + if installPlan.Status.CSVManifestsMatch(steps) { + logger.Infof("found InstallPlan with matching manifests: %s", installPlan.GetName()) + return o.referenceForInstallPlan(installPlan), nil + } + } + logger.Warn("no installplan found with matching manifests, creating new one") + + return o.createInstallPlan(namespace, subs, installPlanApproval, steps) } -func (o *Operator) requeueInstallPlan(name, namespace string) { +func (o *Operator) createInstallPlan(namespace string, subs []*v1alpha1.Subscription, installPlanApproval v1alpha1.Approval, steps []*v1alpha1.Step) (*v1alpha1.InstallPlanReference, error) { + if len(steps) == 0 { + return nil, nil + } + + csvNames := []string{} + catalogSourceMap := map[string]struct{}{} + for _, s := range steps { + if s.Resource.Kind == "ClusterServiceVersion" { + csvNames = append(csvNames, s.Resource.Name) + } + catalogSourceMap[s.Resource.CatalogSource] = struct{}{} + } + catalogSources := []string{} + for s := range catalogSourceMap { + catalogSources = append(catalogSources, s) + } + + phase := v1alpha1.InstallPlanPhaseInstalling + if installPlanApproval == v1alpha1.ApprovalManual { + phase = v1alpha1.InstallPlanPhaseRequiresApproval + } + ip := &v1alpha1.InstallPlan{ + ObjectMeta: metav1.ObjectMeta{ + GenerateName: "install-", + Namespace: namespace, + }, + Spec: v1alpha1.InstallPlanSpec{ + ClusterServiceVersionNames: csvNames, + Approval: installPlanApproval, + Approved: installPlanApproval == v1alpha1.ApprovalAutomatic, + }, + } + for _, sub := range subs { + ownerutil.AddNonBlockingOwner(ip, sub) + } + + res, err := o.client.OperatorsV1alpha1().InstallPlans(namespace).Create(ip) + if err != nil { + return nil, err + } + + res.Status = v1alpha1.InstallPlanStatus{ + Phase: phase, + Plan: steps, + CatalogSources: catalogSources, + } + res, err = o.client.OperatorsV1alpha1().InstallPlans(namespace).UpdateStatus(res) + if err != nil { + return nil, err + } + return o.referenceForInstallPlan(res), nil + +} + +func (o *Operator) referenceForInstallPlan(ip *v1alpha1.InstallPlan) *v1alpha1.InstallPlanReference { + return &v1alpha1.InstallPlanReference{ + UID: ip.GetUID(), + Name: ip.GetName(), + APIVersion: v1alpha1.SchemeGroupVersion.String(), + Kind: v1alpha1.InstallPlanKind, + } +} + +func (o *Operator) requeueSubscription(name, namespace string) { // we can build the key directly, will need to change if queue uses different key scheme key := fmt.Sprintf("%s/%s", namespace, name) o.subQueue.AddRateLimited(key) @@ -241,18 +883,25 @@ func (o *Operator) requeueInstallPlan(name, namespace string) { func (o *Operator) syncInstallPlans(obj interface{}) (syncError error) { plan, ok := obj.(*v1alpha1.InstallPlan) if !ok { - log.Debugf("wrong type: %#v", obj) + o.Log.Debugf("wrong type: %#v", obj) return fmt.Errorf("casting InstallPlan failed") } - logger := log.WithFields(log.Fields{ + logger := o.Log.WithFields(logrus.Fields{ + "id": queueinformer.NewLoopID(), "ip": plan.GetName(), "namespace": plan.GetNamespace(), "phase": plan.Status.Phase, }) logger.Info("syncing") - outInstallPlan, syncError := transitionInstallPlanState(o, *plan) + + if len(plan.Status.Plan) == 0 { + logger.Info("skip processing installplan without status - subscription sync responsible for initial status") + return + } + + outInstallPlan, syncError := transitionInstallPlanState(logger.Logger, o, *plan) if syncError != nil { logger = logger.WithField("syncError", syncError) @@ -266,7 +915,8 @@ func (o *Operator) syncInstallPlans(obj interface{}) (syncError error) { // notify subscription loop of installplan changes if ownerutil.IsOwnedByKind(outInstallPlan, v1alpha1.SubscriptionKind) { oref := ownerutil.GetOwnerByKind(outInstallPlan, v1alpha1.SubscriptionKind) - o.requeueInstallPlan(oref.Name, outInstallPlan.GetNamespace()) + logger.WithField("owner", oref).Debug("requeueing installplan owner") + o.requeueSubscription(oref.Name, outInstallPlan.GetNamespace()) } // Update InstallPlan with status of transition. Log errors if we can't write them to the status. @@ -290,49 +940,21 @@ type installPlanTransitioner interface { var _ installPlanTransitioner = &Operator{} -func transitionInstallPlanState(transitioner installPlanTransitioner, in v1alpha1.InstallPlan) (*v1alpha1.InstallPlan, error) { - logger := log.WithFields(log.Fields{ - "ip": in.GetName(), - "namespace": in.GetNamespace(), - "phase": in.Status.Phase, - }) - +func transitionInstallPlanState(log *logrus.Logger, transitioner installPlanTransitioner, in v1alpha1.InstallPlan) (*v1alpha1.InstallPlan, error) { out := in.DeepCopy() switch in.Status.Phase { - case v1alpha1.InstallPlanPhaseNone: - logger.Debugf("setting phase to %s", v1alpha1.InstallPlanPhasePlanning) - out.Status.Phase = v1alpha1.InstallPlanPhasePlanning - return out, nil - - case v1alpha1.InstallPlanPhasePlanning: - logger.Debug("attempting to resolve") - if err := transitioner.ResolvePlan(out); err != nil { - out.Status.SetCondition(v1alpha1.ConditionFailed(v1alpha1.InstallPlanResolved, - v1alpha1.InstallPlanReasonInstallCheckFailed, err)) - out.Status.Phase = v1alpha1.InstallPlanPhaseFailed - return out, err - } - out.Status.SetCondition(v1alpha1.ConditionMet(v1alpha1.InstallPlanResolved)) - - if out.Spec.Approval == v1alpha1.ApprovalManual && out.Spec.Approved != true { - out.Status.Phase = v1alpha1.InstallPlanPhaseRequiresApproval - } else { - out.Status.Phase = v1alpha1.InstallPlanPhaseInstalling - } - return out, nil - case v1alpha1.InstallPlanPhaseRequiresApproval: if out.Spec.Approved { - logger.Debugf("approved, setting to %s", v1alpha1.InstallPlanPhasePlanning) + log.Debugf("approved, setting to %s", v1alpha1.InstallPlanPhasePlanning) out.Status.Phase = v1alpha1.InstallPlanPhaseInstalling } else { - logger.Debug("not approved, skipping sync") + log.Debug("not approved, skipping sync") } return out, nil case v1alpha1.InstallPlanPhaseInstalling: - logger.Debug("attempting to install") + log.Debug("attempting to install") if err := transitioner.ExecutePlan(out); err != nil { out.Status.SetCondition(v1alpha1.ConditionFailed(v1alpha1.InstallPlanInstalled, v1alpha1.InstallPlanReasonComponentFailed, err)) @@ -349,74 +971,6 @@ func transitionInstallPlanState(transitioner installPlanTransitioner, in v1alpha // ResolvePlan modifies an InstallPlan to contain a Plan in its Status field. func (o *Operator) ResolvePlan(plan *v1alpha1.InstallPlan) error { - if plan.Status.Phase != v1alpha1.InstallPlanPhasePlanning { - panic("attempted to create a plan that wasn't in the planning phase") - } - - if len(o.sources) == 0 { - return fmt.Errorf("cannot resolve InstallPlan without any Catalog Sources") - } - - // Take a snapshot of the included catalog sources - includedNamespaces := map[string]struct{}{ - o.namespace: {}, - plan.Namespace: {}, - } - sourcesSnapshot := o.getSourcesSnapshot(plan, includedNamespaces) - - // Take a snapshot of the existing CRD owners - existingCRDOwners, err := o.getExistingCRDOwners(plan.Namespace) - if err != nil { - return err - } - - // Attempt to resolve the InstallPlan - steps, usedSources, err := o.dependencyResolver.ResolveInstallPlan(sourcesSnapshot, existingCRDOwners, CatalogLabel, plan) - if err != nil { - return err - } - - // Set the resolved steps - plan.Status.Plan = steps - plan.Status.CatalogSources = []string{} - - // Add secrets for each used catalog source - for _, sourceKey := range usedSources { - // Append the used catalog source - plan.Status.CatalogSources = append(plan.Status.CatalogSources, sourceKey.Name) - - // Get the catalog source - catsrc, err := o.client.OperatorsV1alpha1().CatalogSources(sourceKey.Namespace).Get(sourceKey.Name, metav1.GetOptions{}) - if err != nil { - return err - } - - for _, secretName := range catsrc.Spec.Secrets { - // Attempt to look up the secret - _, err := o.OpClient.KubernetesInterface().CoreV1().Secrets(sourceKey.Namespace).Get(secretName, metav1.GetOptions{}) - status := v1alpha1.StepStatusUnknown - if k8serrors.IsNotFound(err) { - status = v1alpha1.StepStatusNotPresent - } else if err == nil { - status = v1alpha1.StepStatusPresent - } else { - return err - } - - // Prepend any required secrets to the plan for that catalog source - plan.Status.Plan = append([]v1alpha1.Step{{ - Resolving: "", - Resource: v1alpha1.StepResource{ - Name: secretName, - Kind: "Secret", - Group: "", - Version: "v1", - }, - Status: status, - }}, plan.Status.Plan...) - } - } - return nil } @@ -426,10 +980,12 @@ func (o *Operator) ExecutePlan(plan *v1alpha1.InstallPlan) error { panic("attempted to install a plan that wasn't in the installing phase") } + namespace := plan.GetNamespace() + // Get the set of initial installplan csv names initialCSVNames := getCSVNameSet(plan) // Get pre-existing CRD owners to make decisions about applying resolved CSVs - existingCRDOwners, err := o.getExistingCRDOwners(plan.GetNamespace()) + existingCRDOwners, err := o.getExistingApiOwners(plan.GetNamespace()) if err != nil { return err } @@ -440,15 +996,14 @@ func (o *Operator) ExecutePlan(plan *v1alpha1.InstallPlan) error { continue case v1alpha1.StepStatusUnknown, v1alpha1.StepStatusNotPresent: - log.Debugf("resource kind: %s", step.Resource.Kind) - log.Debugf("resource name: %s", step.Resource.Name) + o.Log.WithFields(logrus.Fields{"kind": step.Resource.Kind, "name": step.Resource.Name}).Debug("execute resource") switch step.Resource.Kind { case crdKind: // Marshal the manifest into a CRD instance. var crd v1beta1ext.CustomResourceDefinition err := json.Unmarshal([]byte(step.Resource.Manifest), &crd) if err != nil { - return err + return errorwrap.Wrapf(err, "error parsing step manifest: %s", step.Resource.Name) } // TODO: check that names are accepted @@ -471,7 +1026,7 @@ func (o *Operator) ExecutePlan(plan *v1alpha1.InstallPlan) error { var csv v1alpha1.ClusterServiceVersion err := json.Unmarshal([]byte(step.Resource.Manifest), &csv) if err != nil { - return err + return errorwrap.Wrapf(err, "error parsing step manifest: %s", step.Resource.Name) } // Check if the resolved CSV is in the initial set @@ -479,41 +1034,69 @@ func (o *Operator) ExecutePlan(plan *v1alpha1.InstallPlan) error { // Check for pre-existing CSVs that own the same CRDs competingOwners, err := competingCRDOwnersExist(plan.GetNamespace(), &csv, existingCRDOwners) if err != nil { - return err + return errorwrap.Wrapf(err, "error checking crd owners for: %s", csv.GetName()) } // TODO: decide on fail/continue logic for pre-existing dependent CSVs that own the same CRD(s) if competingOwners { // For now, error out - return fmt.Errorf("Pre-existing CRD owners found for owned CRD(s) of dependent CSV %s", csv.GetName()) + return fmt.Errorf("pre-existing CRD owners found for owned CRD(s) of dependent CSV %s", csv.GetName()) } } // Attempt to create the CSV. + csv.SetNamespace(namespace) _, err = o.client.OperatorsV1alpha1().ClusterServiceVersions(csv.GetNamespace()).Create(&csv) if k8serrors.IsAlreadyExists(err) { // If it already existed, mark the step as Present. plan.Status.Plan[i].Status = v1alpha1.StepStatusPresent } else if err != nil { - return err + return errorwrap.Wrapf(err, "error creating csv %s", csv.GetName()) } else { // If no error occurred, mark the step as Created. plan.Status.Plan[i].Status = v1alpha1.StepStatusCreated } + case v1alpha1.SubscriptionKind: + // Marshal the manifest into a subscription instance. + var sub v1alpha1.Subscription + err := json.Unmarshal([]byte(step.Resource.Manifest), &sub) + if err != nil { + return errorwrap.Wrapf(err, "error parsing step manifest: %s", step.Resource.Name) + } + + // Add the InstallPlan's name as an annotation + if annotations := sub.GetAnnotations(); annotations != nil { + annotations[generatedByKey] = plan.GetName() + } else { + sub.SetAnnotations(map[string]string{generatedByKey: plan.GetName()}) + } + // Attempt to create the Subscription + sub.SetNamespace(namespace) + _, err = o.client.OperatorsV1alpha1().Subscriptions(sub.GetNamespace()).Create(&sub) + if k8serrors.IsAlreadyExists(err) { + // If it already existed, mark the step as Present. + plan.Status.Plan[i].Status = v1alpha1.StepStatusPresent + } else if err != nil { + return errorwrap.Wrapf(err, "error creating subscription %s", sub.GetName()) + } else { + // If no error occurred, mark the step as Created. + plan.Status.Plan[i].Status = v1alpha1.StepStatusCreated + } case secretKind: + // TODO: this will confuse bundle users that include secrets in their bundles - this only handles pull secrets // Get the pre-existing secret. secret, err := o.OpClient.KubernetesInterface().CoreV1().Secrets(o.namespace).Get(step.Resource.Name, metav1.GetOptions{}) if k8serrors.IsNotFound(err) { return fmt.Errorf("secret %s does not exist", step.Resource.Name) } else if err != nil { - return err + return errorwrap.Wrapf(err, "error getting pull secret from olm namespace %s", secret.GetName()) } // Set the namespace to the InstallPlan's namespace and attempt to // create a new secret. - secret.Namespace = plan.Namespace - _, err = o.OpClient.KubernetesInterface().CoreV1().Secrets(plan.Namespace).Create(&v1.Secret{ + secret.SetNamespace(namespace) + _, err = o.OpClient.KubernetesInterface().CoreV1().Secrets(plan.Namespace).Create(&corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: secret.Name, Namespace: plan.Namespace, @@ -536,20 +1119,201 @@ func (o *Operator) ExecutePlan(plan *v1alpha1.InstallPlan) error { var cr rbacv1.ClusterRole err := json.Unmarshal([]byte(step.Resource.Manifest), &cr) if err != nil { - return err + return errorwrap.Wrapf(err, "error parsing step manifest: %s", step.Resource.Name) } + // Update UIDs on all CSV OwnerReferences + updated, err := o.getUpdatedOwnerReferences(cr.OwnerReferences, plan.Namespace) + if err != nil { + return errorwrap.Wrapf(err, "error generating ownerrefs for clusterrole %s", cr.GetName()) + } + cr.OwnerReferences = updated + // Attempt to create the ClusterRole. _, err = o.OpClient.KubernetesInterface().RbacV1().ClusterRoles().Create(&cr) if k8serrors.IsAlreadyExists(err) { + _, err = o.OpClient.UpdateClusterRole(&cr) + if err != nil { + return errorwrap.Wrapf(err, "error updating clusterrole %s", cr.GetName()) + } // If it already existed, mark the step as Present. plan.Status.Plan[i].Status = v1alpha1.StepStatusPresent } else if err != nil { - return err + return errorwrap.Wrapf(err, "error creating clusterrole %s", cr.GetName()) } else { // If no error occurred, mark the step as Created. plan.Status.Plan[i].Status = v1alpha1.StepStatusCreated } + case clusterRoleBindingKind: + // Marshal the manifest into a RoleBinding instance. + var rb rbacv1.ClusterRoleBinding + err := json.Unmarshal([]byte(step.Resource.Manifest), &rb) + if err != nil { + return errorwrap.Wrapf(err, "error parsing step manifest: %s", step.Resource.Name) + } + + // Update UIDs on all CSV OwnerReferences + updated, err := o.getUpdatedOwnerReferences(rb.OwnerReferences, plan.Namespace) + if err != nil { + return errorwrap.Wrapf(err, "error generating ownerrefs for clusterrolebinding %s", rb.GetName()) + } + rb.OwnerReferences = updated + + // Attempt to create the ClusterRoleBinding. + _, err = o.OpClient.KubernetesInterface().RbacV1().ClusterRoleBindings().Create(&rb) + if k8serrors.IsAlreadyExists(err) { + rb.SetNamespace(plan.Namespace) + _, err = o.OpClient.UpdateClusterRoleBinding(&rb) + if err != nil { + return errorwrap.Wrapf(err, "error updating clusterrolebinding %s", rb.GetName()) + } + + // If it already existed, mark the step as Present. + plan.Status.Plan[i].Status = v1alpha1.StepStatusPresent + } else if err != nil { + return errorwrap.Wrapf(err, "error creating clusterrolebinding %s", rb.GetName()) + } else { + // If no error occurred, mark the step as Created. + plan.Status.Plan[i].Status = v1alpha1.StepStatusCreated + } + + case roleKind: + // Marshal the manifest into a Role instance. + var r rbacv1.Role + err := json.Unmarshal([]byte(step.Resource.Manifest), &r) + if err != nil { + return errorwrap.Wrapf(err, "error parsing step manifest: %s", step.Resource.Name) + } + + // Update UIDs on all CSV OwnerReferences + updated, err := o.getUpdatedOwnerReferences(r.OwnerReferences, plan.Namespace) + if err != nil { + return errorwrap.Wrapf(err, "error generating ownerrefs for role %s", r.GetName()) + } + r.SetOwnerReferences(updated) + r.SetNamespace(namespace) + + // Attempt to create the Role. + _, err = o.OpClient.KubernetesInterface().RbacV1().Roles(plan.Namespace).Create(&r) + if k8serrors.IsAlreadyExists(err) { + // If it already existed, mark the step as Present. + r.SetNamespace(plan.Namespace) + _, err = o.OpClient.UpdateRole(&r) + if err != nil { + return errorwrap.Wrapf(err, "error updating role %s", r.GetName()) + } + + plan.Status.Plan[i].Status = v1alpha1.StepStatusPresent + } else if err != nil { + return errorwrap.Wrapf(err, "error creating role %s", r.GetName()) + } else { + // If no error occurred, mark the step as Created. + plan.Status.Plan[i].Status = v1alpha1.StepStatusCreated + } + + case roleBindingKind: + // Marshal the manifest into a RoleBinding instance. + var rb rbacv1.RoleBinding + err := json.Unmarshal([]byte(step.Resource.Manifest), &rb) + if err != nil { + return errorwrap.Wrapf(err, "error parsing step manifest: %s", step.Resource.Name) + } + + // Update UIDs on all CSV OwnerReferences + updated, err := o.getUpdatedOwnerReferences(rb.OwnerReferences, plan.Namespace) + if err != nil { + return errorwrap.Wrapf(err, "error generating ownerrefs for rolebinding %s", rb.GetName()) + } + rb.SetOwnerReferences(updated) + rb.SetNamespace(namespace) + + // Attempt to create the RoleBinding. + _, err = o.OpClient.KubernetesInterface().RbacV1().RoleBindings(plan.Namespace).Create(&rb) + if k8serrors.IsAlreadyExists(err) { + rb.SetNamespace(plan.Namespace) + _, err = o.OpClient.UpdateRoleBinding(&rb) + if err != nil { + return errorwrap.Wrapf(err, "error updating rolebinding %s", rb.GetName()) + } + + // If it already existed, mark the step as Present. + plan.Status.Plan[i].Status = v1alpha1.StepStatusPresent + } else if err != nil { + return errorwrap.Wrapf(err, "error creating rolebinding %s", rb.GetName()) + } else { + // If no error occurred, mark the step as Created. + plan.Status.Plan[i].Status = v1alpha1.StepStatusCreated + } + + case serviceAccountKind: + // Marshal the manifest into a ServiceAccount instance. + var sa corev1.ServiceAccount + err := json.Unmarshal([]byte(step.Resource.Manifest), &sa) + if err != nil { + return errorwrap.Wrapf(err, "error parsing step manifest: %s", step.Resource.Name) + } + + // Update UIDs on all CSV OwnerReferences + updated, err := o.getUpdatedOwnerReferences(sa.OwnerReferences, plan.Namespace) + if err != nil { + return errorwrap.Wrapf(err, "error generating ownerrefs for service account: %s", sa.GetName()) + } + sa.SetOwnerReferences(updated) + sa.SetNamespace(namespace) + + // Attempt to create the ServiceAccount. + _, err = o.OpClient.KubernetesInterface().CoreV1().ServiceAccounts(plan.Namespace).Create(&sa) + if k8serrors.IsAlreadyExists(err) { + // If it already exists we need to patch the existing SA with the new OwnerReferences + sa.SetNamespace(plan.Namespace) + _, err = o.OpClient.UpdateServiceAccount(&sa) + if err != nil { + return errorwrap.Wrapf(err, "error updating service account: %s", sa.GetName()) + } + + // Mark as present + plan.Status.Plan[i].Status = v1alpha1.StepStatusPresent + } else if err != nil { + return errorwrap.Wrapf(err, "error creating service account: %s", sa.GetName()) + } else { + // If no error occurred, mark the step as Created. + plan.Status.Plan[i].Status = v1alpha1.StepStatusCreated + } + + case serviceKind: + // Marshal the manifest into a Service instance + var s corev1.Service + err := json.Unmarshal([]byte(step.Resource.Manifest), &s) + if err != nil { + return errorwrap.Wrapf(err, "error parsing step manifest: %s", step.Resource.Name) + } + + // Update UIDs on all CSV OwnerReferences + updated, err := o.getUpdatedOwnerReferences(s.OwnerReferences, plan.Namespace) + if err != nil { + return errorwrap.Wrapf(err, "error generating ownerrefs for service: %s", s.GetName()) + } + s.SetOwnerReferences(updated) + s.SetNamespace(namespace) + + // Attempt to create the Service + _, err = o.OpClient.KubernetesInterface().CoreV1().Services(plan.Namespace).Create(&s) + if k8serrors.IsAlreadyExists(err) { + // If it already exists we need to patch the existing SA with the new OwnerReferences + s.SetNamespace(plan.Namespace) + _, err = o.OpClient.UpdateService(&s) + if err != nil { + return errorwrap.Wrapf(err, "error updating service: %s", s.GetName()) + } + + // Mark as present + plan.Status.Plan[i].Status = v1alpha1.StepStatusPresent + } else if err != nil { + return errorwrap.Wrapf(err, "error creating service: %s", s.GetName()) + } else { + // If no error occurred, mark the step as Created + plan.Status.Plan[i].Status = v1alpha1.StepStatusCreated + } default: return v1alpha1.ErrInvalidInstallPlan @@ -572,34 +1336,9 @@ func (o *Operator) ExecutePlan(plan *v1alpha1.InstallPlan) error { return nil } -func (o *Operator) getSourcesSnapshot(plan *v1alpha1.InstallPlan, includedNamespaces map[string]struct{}) []registry.SourceRef { - o.sourcesLock.RLock() - defer o.sourcesLock.RUnlock() - sourcesSnapshot := []registry.SourceRef{} - - for key, source := range o.sources { - // Only copy catalog sources in included namespaces - if _, ok := includedNamespaces[key.Namespace]; ok { - ref := registry.SourceRef{ - Source: source, - SourceKey: key, - } - if key.Name == plan.Spec.CatalogSource && key.Namespace == plan.Spec.CatalogSourceNamespace { - // Prepend preffered catalog source - sourcesSnapshot = append([]registry.SourceRef{ref}, sourcesSnapshot...) - } else { - // Append the catalog source - sourcesSnapshot = append(sourcesSnapshot, ref) - } - } - } - - return sourcesSnapshot -} - -// getExistingCRDOwners creates a map of CRD names to existing owner CSVs in the given namespace -func (o *Operator) getExistingCRDOwners(namespace string) (map[string][]string, error) { - // Get a list of CSV CRs in the namespace +// getExistingApiOwners creates a map of CRD names to existing owner CSVs in the given namespace +func (o *Operator) getExistingApiOwners(namespace string) (map[string][]string, error) { + // Get a list of CSVs in the namespace csvList, err := o.client.OperatorsV1alpha1().ClusterServiceVersions(namespace).List(metav1.ListOptions{}) if err != nil { @@ -612,11 +1351,30 @@ func (o *Operator) getExistingCRDOwners(namespace string) (map[string][]string, for _, crd := range csv.Spec.CustomResourceDefinitions.Owned { owners[crd.Name] = append(owners[crd.Name], csv.GetName()) } + for _, api := range csv.Spec.APIServiceDefinitions.Owned { + owners[api.Group] = append(owners[api.Group], csv.GetName()) + } } return owners, nil } +func (o *Operator) getUpdatedOwnerReferences(refs []metav1.OwnerReference, namespace string) ([]metav1.OwnerReference, error) { + updated := append([]metav1.OwnerReference(nil), refs...) + + for i, owner := range refs { + if owner.Kind == v1alpha1.ClusterServiceVersionKind { + csv, err := o.client.OperatorsV1alpha1().ClusterServiceVersions(namespace).Get(owner.Name, metav1.GetOptions{}) + if err != nil { + return nil, err + } + owner.UID = csv.GetUID() + updated[i] = owner + } + } + return updated, nil +} + // competingCRDOwnersExist returns true if there exists a CSV that owns at least one of the given CSVs owned CRDs (that's not the given CSV) func competingCRDOwnersExist(namespace string, csv *v1alpha1.ClusterServiceVersion, existingOwners map[string][]string) (bool, error) { // Attempt to find a pre-existing owner in the namespace for any owned crd diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/catalog/subscriptions.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/catalog/subscriptions.go index 246b402fa0..8cea6b8be0 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/catalog/subscriptions.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/catalog/subscriptions.go @@ -2,14 +2,8 @@ package catalog import ( "errors" - "fmt" "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" - "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry" - - "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil" - log "github.com/sirupsen/logrus" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) var ( @@ -17,127 +11,28 @@ var ( ) const ( - PackageLabel = "alm-package" - CatalogLabel = "alm-catalog" - ChannelLabel = "alm-channel" + PackageLabel = "olm.package" + CatalogLabel = "olm.catalog" + CatalogNamespaceLabel = "olm.catalog.namespace" + ChannelLabel = "olm.channel" ) -// FIXME(alecmerdler): Rewrite this whole block to be more clear -func (o *Operator) syncSubscription(in *v1alpha1.Subscription) (*v1alpha1.Subscription, error) { - if in == nil || in.Spec == nil { - return nil, ErrNilSubscription - } - out := in.DeepCopy() - out = ensureLabels(out) - - // Only sync if catalog has been updated since last sync time - if o.sourcesLastUpdate.Before(&out.Status.LastUpdated) && out.Status.State == v1alpha1.SubscriptionStateAtLatest { - log.Infof("skipping sync: no new updates to catalog since last sync at %s", - out.Status.LastUpdated.String()) - return nil, nil - } - - o.sourcesLock.Lock() - defer o.sourcesLock.Unlock() - - catalogNamespace := out.Spec.CatalogSourceNamespace - if catalogNamespace == "" { - catalogNamespace = o.namespace - } - catalog, ok := o.sources[registry.ResourceKey{Name: out.Spec.CatalogSource, Namespace: catalogNamespace}] - if !ok { - out.Status.State = v1alpha1.SubscriptionStateAtLatest - out.Status.Reason = v1alpha1.SubscriptionReasonInvalidCatalog - return out, fmt.Errorf("unknown catalog source %s in namespace %s", out.Spec.CatalogSource, catalogNamespace) - } - - // Find latest CSV if no CSVs are installed already - if out.Status.CurrentCSV == "" { - if out.Spec.StartingCSV != "" { - out.Status.CurrentCSV = out.Spec.StartingCSV - } else { - csv, err := catalog.FindCSVForPackageNameUnderChannel(out.Spec.Package, out.Spec.Channel) - if err != nil { - return out, fmt.Errorf("failed to find CSV for package %s in channel %s: %v", out.Spec.Package, out.Spec.Channel, err) - } - if csv == nil { - return out, fmt.Errorf("failed to find CSV for package %s in channel %s: nil CSV", out.Spec.Package, out.Spec.Channel) - } - out.Status.CurrentCSV = csv.GetName() - } - out.Status.State = v1alpha1.SubscriptionStateUpgradeAvailable - return out, nil - } - - // Check that desired CSV has been installed - csv, err := o.client.OperatorsV1alpha1().ClusterServiceVersions(out.GetNamespace()).Get(out.Status.CurrentCSV, metav1.GetOptions{}) - if err != nil || csv == nil { - log.Infof("error fetching CSV %s via k8s api: %v", out.Status.CurrentCSV, err) - if out.Status.Install != nil && out.Status.Install.Name != "" { - ip, err := o.client.OperatorsV1alpha1().InstallPlans(out.GetNamespace()).Get(out.Status.Install.Name, metav1.GetOptions{}) - if err != nil { - log.Errorf("get installplan %s error: %v", out.Status.Install.Name, err) - } - if err == nil && ip != nil { - log.Infof("installplan for %s already exists", out.Status.CurrentCSV) - return out, nil - } - log.Infof("installplan %s not found: creating new plan", out.Status.Install.Name) - out.Status.Install = nil - } - - // Install CSV if doesn't exist - out.Status.State = v1alpha1.SubscriptionStateUpgradePending - ip := &v1alpha1.InstallPlan{ - ObjectMeta: metav1.ObjectMeta{}, - Spec: v1alpha1.InstallPlanSpec{ - ClusterServiceVersionNames: []string{out.Status.CurrentCSV}, - Approval: out.GetInstallPlanApproval(), - }, - } - ownerutil.AddNonBlockingOwner(ip, out) - ip.SetGenerateName(fmt.Sprintf("install-%s-", out.Status.CurrentCSV)) - ip.SetNamespace(out.GetNamespace()) - - // Inherit the subscription's catalog source - ip.Spec.CatalogSource = out.Spec.CatalogSource - ip.Spec.CatalogSourceNamespace = out.Spec.CatalogSourceNamespace - - res, err := o.client.OperatorsV1alpha1().InstallPlans(out.GetNamespace()).Create(ip) - if err != nil { - return out, fmt.Errorf("failed to ensure current CSV %s installed: %v", out.Status.CurrentCSV, err) - } - if res == nil { - return out, errors.New("unexpected installplan returned by k8s api on create: ") - } - out.Status.Install = &v1alpha1.InstallPlanReference{ - UID: res.GetUID(), - Name: res.GetName(), - APIVersion: v1alpha1.SchemeGroupVersion.String(), - Kind: v1alpha1.InstallPlanKind, - } - return out, nil +func labelsForSubscription(sub *v1alpha1.Subscription) map[string]string { + return map[string]string{ + PackageLabel: sub.Spec.Package, + CatalogLabel: sub.Spec.CatalogSource, + CatalogNamespaceLabel: sub.Spec.CatalogSourceNamespace, + ChannelLabel: sub.Spec.Channel, } +} - // Set the installed CSV - out.Status.InstalledCSV = out.Status.CurrentCSV - - // Poll catalog for an update - repl, err := catalog.FindReplacementCSVForPackageNameUnderChannel(out.Spec.Package, out.Spec.Channel, out.Status.CurrentCSV) - if err != nil { - out.Status.State = v1alpha1.SubscriptionStateAtLatest - return out, fmt.Errorf("failed to lookup replacement CSV for %s: %v", out.Status.CurrentCSV, err) - } - if repl == nil { - out.Status.State = v1alpha1.SubscriptionStateAtLatest - return out, fmt.Errorf("nil replacement CSV for %s returned from catalog", out.Status.CurrentCSV) +// TODO remove this once UI no longer needs them +func legacyLabelsForSubscription(sub *v1alpha1.Subscription) map[string]string { + return map[string]string{ + "alm-package": sub.Spec.Package, + "alm-catalog": sub.Spec.CatalogSource, + "alm-channel": sub.Spec.Channel, } - - // Update subscription with new latest - out.Status.CurrentCSV = repl.GetName() - out.Status.Install = nil - out.Status.State = v1alpha1.SubscriptionStateUpgradeAvailable - return out, nil } func ensureLabels(sub *v1alpha1.Subscription) *v1alpha1.Subscription { @@ -145,9 +40,12 @@ func ensureLabels(sub *v1alpha1.Subscription) *v1alpha1.Subscription { if labels == nil { labels = map[string]string{} } - labels[PackageLabel] = sub.Spec.Package - labels[CatalogLabel] = sub.Spec.CatalogSource - labels[ChannelLabel] = sub.Spec.Channel + for k, v := range labelsForSubscription(sub) { + labels[k] = v + } + for k, v := range legacyLabelsForSubscription(sub) { + labels[k] = v + } sub.SetLabels(labels) return sub } diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/olm/apiservices.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/olm/apiservices.go new file mode 100644 index 0000000000..2c0860c115 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/olm/apiservices.go @@ -0,0 +1,761 @@ +package olm + +import ( + "fmt" + "strings" + "time" + + log "github.com/sirupsen/logrus" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + k8serrors "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/intstr" + apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" + + "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/certs" + olmerrors "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/errors" + "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install" + "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil" +) + +const ( + // DefaultCertMinFresh is the default min-fresh value - 1 day + DefaultCertMinFresh = time.Hour * 24 + // DefaultCertValidFor is the default duration a cert can be valid for - 2 years + DefaultCertValidFor = time.Hour * 24 * 730 + // OLMCAHashAnnotationKey is the label key used to store the hash of the CA cert + OLMCAHashAnnotationKey = "olmcahash" + // Organization is the organization name used in the generation of x509 certs + Organization = "Red Hat, Inc." +) + +func (a *Operator) shouldRotateCerts(csv *v1alpha1.ClusterServiceVersion) bool { + now := metav1.Now() + if !csv.Status.CertsRotateAt.IsZero() && csv.Status.CertsRotateAt.Before(&now) { + return true + } + + return false +} + +// apiServiceResourceErrorActionable returns true if OLM can do something about any one +// of the apiService errors in errs; otherwise returns false +// +// This method can be used to determine if a CSV in a failed state due to APIService +// issues can resolve them by reinstalling +func (a *Operator) apiServiceResourceErrorActionable(err error) bool { + filtered := utilerrors.FilterOut(err, func(e error) bool { + _, unadoptable := e.(olmerrors.UnadoptableError) + return !unadoptable + }) + actionable := filtered == nil + + return actionable +} + +// checkAPIServiceResources checks if all expected generated resources for the given APIService exist +func (a *Operator) checkAPIServiceResources(csv *v1alpha1.ClusterServiceVersion, hashFunc certs.PEMHash) error { + logger := log.WithFields(log.Fields{ + "csv": csv.GetName(), + "namespace": csv.GetNamespace(), + }) + + errs := []error{} + owners := []ownerutil.Owner{csv} + + // Get replacing CSV if exists + replacing, err := a.lister.OperatorsV1alpha1().ClusterServiceVersionLister().ClusterServiceVersions(csv.GetNamespace()).Get(csv.Spec.Replaces) + if err != nil && !k8serrors.IsNotFound(err) { + logger.WithError(err).Warn("could not get replacement csv") + return err + } + if replacing != nil { + owners = append(owners, replacing) + } + + ruleChecker := install.NewCSVRuleChecker(a.lister.RbacV1().RoleLister(), a.lister.RbacV1().RoleBindingLister(), a.lister.RbacV1().ClusterRoleLister(), a.lister.RbacV1().ClusterRoleBindingLister(), csv) + for _, desc := range csv.GetOwnedAPIServiceDescriptions() { + apiServiceName := desc.GetName() + logger := logger.WithFields(log.Fields{ + "apiservice": apiServiceName, + }) + + apiService, err := a.lister.APIRegistrationV1().APIServiceLister().Get(apiServiceName) + if err != nil { + logger.Warnf("could not retrieve generated APIService") + errs = append(errs, err) + continue + } + + // Check if the APIService is adoptable + if !ownerutil.AdoptableLabels(apiService.GetLabels(), true, owners...) { + logger.WithFields(log.Fields{"obj": "apiService", "labels": apiService.GetLabels()}).Debug("adoption failed") + err := olmerrors.NewUnadoptableError("", apiServiceName) + logger.WithError(err).Warn("found unadoptable apiservice") + errs = append(errs, err) + return utilerrors.NewAggregate(errs) + } + + serviceName := APIServiceNameToServiceName(apiServiceName) + service, err := a.lister.CoreV1().ServiceLister().Services(csv.GetNamespace()).Get(serviceName) + if err != nil { + logger.WithField("service", serviceName).Warnf("could not retrieve generated Service") + errs = append(errs, err) + continue + } + + // Check if the APIService points to the correct service + if apiService.Spec.Service.Name != serviceName || apiService.Spec.Service.Namespace != csv.GetNamespace() { + logger.WithFields(log.Fields{"service": apiService.Spec.Service.Name, "serviceNamespace": apiService.Spec.Service.Namespace}).Warnf("APIService service reference mismatch") + errs = append(errs, fmt.Errorf("APIService service reference mismatch")) + continue + } + + // Check if CA is Active + caBundle := apiService.Spec.CABundle + ca, err := certs.PEMToCert(caBundle) + if err != nil { + logger.Warnf("could not convert APIService CA bundle to x509 cert") + errs = append(errs, err) + continue + } + if !certs.Active(ca) { + logger.Warnf("CA cert not active") + errs = append(errs, fmt.Errorf("CA cert not active")) + continue + } + + // Check if serving cert is active + secretName := apiServiceName + "-cert" + secret, err := a.lister.CoreV1().SecretLister().Secrets(csv.GetNamespace()).Get(secretName) + if err != nil { + logger.WithField("secret", secretName).Warnf("could not retrieve generated Secret") + errs = append(errs, err) + continue + } + cert, err := certs.PEMToCert(secret.Data["tls.crt"]) + if err != nil { + logger.Warnf("could not convert serving cert to x509 cert") + errs = append(errs, err) + continue + } + if !certs.Active(cert) { + logger.Warnf("serving cert not active") + errs = append(errs, fmt.Errorf("serving cert not active")) + continue + } + + // Check if CA hash matches expected + caHash := hashFunc(caBundle) + if hash, ok := secret.GetAnnotations()[OLMCAHashAnnotationKey]; !ok || hash != caHash { + logger.WithField("secret", secretName).Warnf("secret CA cert hash does not match expected") + errs = append(errs, fmt.Errorf("secret %s CA cert hash does not match expected", secretName)) + continue + } + + // Check if serving cert is trusted by the CA + hosts := []string{ + fmt.Sprintf("%s.%s", service.GetName(), csv.GetNamespace()), + fmt.Sprintf("%s.%s.svc", service.GetName(), csv.GetNamespace()), + } + for _, host := range hosts { + if err := certs.VerifyCert(ca, cert, host); err != nil { + errs = append(errs, fmt.Errorf("could not verify cert: %s", err.Error())) + continue + } + } + + // Ensure the existing Deployment has a matching CA hash annotation + deployment, err := a.lister.AppsV1().DeploymentLister().Deployments(csv.GetNamespace()).Get(desc.DeploymentName) + if k8serrors.IsNotFound(err) || err != nil { + logger.WithField("deployment", desc.DeploymentName).Warnf("expected Deployment could not be retrieved") + errs = append(errs, err) + continue + } + if hash, ok := deployment.Spec.Template.GetAnnotations()[OLMCAHashAnnotationKey]; !ok || hash != caHash { + logger.WithField("deployment", desc.DeploymentName).Warnf("Deployment CA cert hash does not match expected") + errs = append(errs, fmt.Errorf("Deployment %s CA cert hash does not match expected", desc.DeploymentName)) + continue + } + + // Ensure the Deployment's ServiceAccount exists + serviceAccountName := deployment.Spec.Template.Spec.ServiceAccountName + if serviceAccountName == "" { + serviceAccountName = "default" + } + serviceAccount, err := a.lister.CoreV1().ServiceAccountLister().ServiceAccounts(deployment.GetNamespace()).Get(serviceAccountName) + if err != nil { + logger.WithField("serviceaccount", serviceAccountName).Warnf("could not retrieve ServiceAccount") + errs = append(errs, err) + continue + } + + // Ensure RBAC permissions for the APIService are correct + rulesMap := map[string][]rbacv1.PolicyRule{ + // Serving cert Secret Rule + csv.GetNamespace(): { + { + Verbs: []string{"get"}, + APIGroups: []string{""}, + Resources: []string{"secrets"}, + ResourceNames: []string{secret.GetName()}, + }, + }, + "kube-system": {}, + metav1.NamespaceAll: {}, + } + + // extension-apiserver-authentication-reader + authReaderRole, err := a.lister.RbacV1().RoleLister().Roles("kube-system").Get("extension-apiserver-authentication-reader") + if err != nil { + logger.Warnf("could not retrieve Role extension-apiserver-authentication-reader") + errs = append(errs, err) + continue + } + rulesMap["kube-system"] = append(rulesMap["kube-system"], authReaderRole.Rules...) + + // system:auth-delegator + authDelegatorClusterRole, err := a.lister.RbacV1().ClusterRoleLister().Get("system:auth-delegator") + if err != nil { + logger.Warnf("could not retrieve ClusterRole system:auth-delegator") + errs = append(errs, err) + continue + } + rulesMap[metav1.NamespaceAll] = append(rulesMap[metav1.NamespaceAll], authDelegatorClusterRole.Rules...) + + for namespace, rules := range rulesMap { + for _, rule := range rules { + satisfied, err := ruleChecker.RuleSatisfied(serviceAccount, namespace, rule) + if err != nil { + logger.WithField("rule", fmt.Sprintf("%+v", rule)).Warnf("error checking Rule") + errs = append(errs, err) + continue + } + if !satisfied { + logger.WithField("rule", fmt.Sprintf("%+v", rule)).Warnf("Rule not satisfied") + errs = append(errs, fmt.Errorf("Rule %+v not satisfied", rule)) + continue + } + } + } + } + + return utilerrors.NewAggregate(errs) +} + +func (a *Operator) isAPIServiceAvailable(apiService *apiregistrationv1.APIService) bool { + for _, c := range apiService.Status.Conditions { + if c.Type == apiregistrationv1.Available && c.Status == apiregistrationv1.ConditionTrue { + return true + } + } + return false +} + +func (a *Operator) areAPIServicesAvailable(csv *v1alpha1.ClusterServiceVersion) (bool, error) { + for _, desc := range csv.Spec.APIServiceDefinitions.Owned { + apiService, err := a.lister.APIRegistrationV1().APIServiceLister().Get(desc.GetName()) + if k8serrors.IsNotFound(err) { + return false, nil + } + + if err != nil { + return false, err + } + + if !a.isAPIServiceAvailable(apiService) { + return false, nil + } + + if err := a.isGVKRegistered(desc.Group, desc.Version, desc.Kind); err != nil { + return false, nil + } + } + + return true, nil +} + +func (a *Operator) installOwnedAPIServiceRequirements(csv *v1alpha1.ClusterServiceVersion, strategy install.Strategy) (install.Strategy, error) { + logger := log.WithFields(log.Fields{ + "csv": csv.GetName(), + "namespace": csv.GetNamespace(), + }) + + // Assume the strategy is for a deployment + strategyDetailsDeployment, ok := strategy.(*install.StrategyDetailsDeployment) + if !ok { + return nil, fmt.Errorf("unsupported InstallStrategy type") + } + + // Return early if there are no owned APIServices + if len(csv.Spec.APIServiceDefinitions.Owned) == 0 { + return strategyDetailsDeployment, nil + } + + // Create the CA + expiration := time.Now().Add(DefaultCertValidFor) + ca, err := certs.GenerateCA(expiration, Organization) + if err != nil { + logger.Debug("failed to generate CA") + return nil, err + } + rotateAt := expiration.Add(-1 * DefaultCertMinFresh) + + depSpecs := make(map[string]appsv1.DeploymentSpec) + for _, sddSpec := range strategyDetailsDeployment.DeploymentSpecs { + depSpecs[sddSpec.Name] = sddSpec.Spec + } + + // Create all resources required, and update the matching DeploymentSpec's Volume and VolumeMounts + apiDescs := csv.GetOwnedAPIServiceDescriptions() + for _, desc := range apiDescs { + depSpec, ok := depSpecs[desc.DeploymentName] + if !ok { + return nil, fmt.Errorf("StrategyDetailsDeployment missing deployment %s for owned APIService %s", desc.DeploymentName, fmt.Sprintf("%s.%s", desc.Version, desc.Group)) + } + + newDepSpec, err := a.installAPIServiceRequirements(desc, ca, rotateAt, depSpec, csv) + if err != nil { + return nil, err + } + depSpecs[desc.DeploymentName] = *newDepSpec + } + + // Replace all matching DeploymentSpecs in the strategy + for i, sddSpec := range strategyDetailsDeployment.DeploymentSpecs { + if depSpec, ok := depSpecs[sddSpec.Name]; ok { + strategyDetailsDeployment.DeploymentSpecs[i].Spec = depSpec + } + } + + // Set CSV cert status + csv.Status.CertsLastUpdated = metav1.Now() + csv.Status.CertsRotateAt = metav1.NewTime(rotateAt) + + return strategyDetailsDeployment, nil +} + +func (a *Operator) installAPIServiceRequirements(desc v1alpha1.APIServiceDescription, ca *certs.KeyPair, rotateAt time.Time, depSpec appsv1.DeploymentSpec, csv *v1alpha1.ClusterServiceVersion) (*appsv1.DeploymentSpec, error) { + apiServiceName := fmt.Sprintf("%s.%s", desc.Version, desc.Group) + logger := log.WithFields(log.Fields{ + "csv": csv.GetName(), + "namespace": csv.GetNamespace(), + "apiservice": apiServiceName, + }) + + // Create a service for the deployment + containerPort := 443 + if desc.ContainerPort > 0 { + containerPort = int(desc.ContainerPort) + } + service := &corev1.Service{ + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{ + { + Port: int32(443), + TargetPort: intstr.FromInt(containerPort), + }, + }, + Selector: depSpec.Selector.MatchLabels, + }, + } + service.SetName(APIServiceNameToServiceName(apiServiceName)) + service.SetNamespace(csv.GetNamespace()) + ownerutil.AddNonBlockingOwner(service, csv) + + existingService, err := a.lister.CoreV1().ServiceLister().Services(csv.GetNamespace()).Get(service.GetName()) + if err == nil { + if !ownerutil.Adoptable(csv, existingService.GetOwnerReferences()) { + return nil, fmt.Errorf("service %s not safe to replace: extraneous ownerreferences found", service.GetName()) + } + service.SetOwnerReferences(append(service.GetOwnerReferences(), existingService.GetOwnerReferences()...)) + + // Delete the Service to replace + deleteErr := a.OpClient.DeleteService(service.GetNamespace(), service.GetName(), &metav1.DeleteOptions{}) + if err != nil && !k8serrors.IsNotFound(deleteErr) { + return nil, fmt.Errorf("could not delete existing service %s", service.GetName()) + } + } + + // Attempt to create the Service + _, err = a.OpClient.CreateService(service) + if err != nil { + logger.Warnf("could not create service %s", service.GetName()) + return nil, fmt.Errorf("could not create service %s: %s", service.GetName(), err.Error()) + } + + // Create signed serving cert + hosts := []string{ + fmt.Sprintf("%s.%s", service.GetName(), csv.GetNamespace()), + fmt.Sprintf("%s.%s.svc", service.GetName(), csv.GetNamespace()), + } + servingPair, err := certs.CreateSignedServingPair(rotateAt, Organization, ca, hosts) + if err != nil { + logger.Warnf("could not generate signed certs for hosts %v", hosts) + return nil, err + } + + // Create Secret for serving cert + certPEM, privPEM, err := servingPair.ToPEM() + if err != nil { + logger.Warnf("unable to convert serving certificate and private key to PEM format for APIService %s", apiServiceName) + return nil, err + } + + secret := &corev1.Secret{ + Data: map[string][]byte{ + "tls.crt": certPEM, + "tls.key": privPEM, + }, + Type: corev1.SecretTypeTLS, + } + secret.SetName(apiServiceName + "-cert") + secret.SetNamespace(csv.GetNamespace()) + + // Add olmcasha hash as a label to the + caPEM, _, err := ca.ToPEM() + if err != nil { + logger.Warnf("unable to convert CA certificate to PEM format for APIService %s", apiServiceName) + return nil, err + } + caHash := certs.PEMSHA256(caPEM) + secret.SetAnnotations(map[string]string{OLMCAHashAnnotationKey: caHash}) + + existingSecret, err := a.lister.CoreV1().SecretLister().Secrets(csv.GetNamespace()).Get(secret.GetName()) + if err == nil { + // Check if the only owners are this CSV or in this CSV's replacement chain + if ownerutil.Adoptable(csv, existingSecret.GetOwnerReferences()) { + ownerutil.AddNonBlockingOwner(secret, csv) + } + + // Attempt an update + if _, err := a.OpClient.UpdateSecret(secret); err != nil { + logger.Warnf("could not update secret %s", secret.GetName()) + return nil, err + } + } else if k8serrors.IsNotFound(err) { + // Create the secret + ownerutil.AddNonBlockingOwner(secret, csv) + _, err = a.OpClient.CreateSecret(secret) + if err != nil { + log.Warnf("could not create secret %s", secret.GetName()) + return nil, err + } + } else { + return nil, err + } + + // create Role and RoleBinding to allow the deployment to mount the Secret + secretRole := &rbacv1.Role{ + Rules: []rbacv1.PolicyRule{ + { + Verbs: []string{"get"}, + APIGroups: []string{""}, + Resources: []string{"secrets"}, + ResourceNames: []string{secret.GetName()}, + }, + }, + } + secretRole.SetName(secret.GetName()) + secretRole.SetNamespace(csv.GetNamespace()) + + existingSecretRole, err := a.lister.RbacV1().RoleLister().Roles(csv.GetNamespace()).Get(secretRole.GetName()) + if err == nil { + // Check if the only owners are this CSV or in this CSV's replacement chain + if ownerutil.Adoptable(csv, existingSecretRole.GetOwnerReferences()) { + ownerutil.AddNonBlockingOwner(secretRole, csv) + } + + // Attempt an update + if _, err := a.OpClient.UpdateRole(secretRole); err != nil { + logger.Warnf("could not update secret role %s", secretRole.GetName()) + return nil, err + } + } else if k8serrors.IsNotFound(err) { + // Create the role + ownerutil.AddNonBlockingOwner(secretRole, csv) + _, err = a.OpClient.CreateRole(secretRole) + if err != nil { + log.Warnf("could not create secret role %s", secretRole.GetName()) + return nil, err + } + } else { + return nil, err + } + + if depSpec.Template.Spec.ServiceAccountName == "" { + depSpec.Template.Spec.ServiceAccountName = "default" + } + + secretRoleBinding := &rbacv1.RoleBinding{ + Subjects: []rbacv1.Subject{ + { + Kind: "ServiceAccount", + APIGroup: "", + Name: depSpec.Template.Spec.ServiceAccountName, + Namespace: csv.GetNamespace(), + }, + }, + RoleRef: rbacv1.RoleRef{ + APIGroup: "rbac.authorization.k8s.io", + Kind: "Role", + Name: secretRole.GetName(), + }, + } + secretRoleBinding.SetName(secret.GetName()) + secretRoleBinding.SetNamespace(csv.GetNamespace()) + + existingSecretRoleBinding, err := a.lister.RbacV1().RoleBindingLister().RoleBindings(csv.GetNamespace()).Get(secretRoleBinding.GetName()) + if err == nil { + // Check if the only owners are this CSV or in this CSV's replacement chain + if ownerutil.Adoptable(csv, existingSecretRoleBinding.GetOwnerReferences()) { + ownerutil.AddNonBlockingOwner(secretRoleBinding, csv) + } + + // Attempt an update + if _, err := a.OpClient.UpdateRoleBinding(secretRoleBinding); err != nil { + logger.Warnf("could not update secret rolebinding %s", secretRoleBinding.GetName()) + return nil, err + } + } else if k8serrors.IsNotFound(err) { + // Create the role + ownerutil.AddNonBlockingOwner(secretRoleBinding, csv) + _, err = a.OpClient.CreateRoleBinding(secretRoleBinding) + if err != nil { + log.Warnf("could not create secret rolebinding with dep spec: %+v", depSpec) + return nil, err + } + } else { + return nil, err + } + + // create ClusterRoleBinding to system:auth-delegator Role + authDelegatorClusterRoleBinding := &rbacv1.ClusterRoleBinding{ + Subjects: []rbacv1.Subject{ + { + Kind: "ServiceAccount", + APIGroup: "", + Name: depSpec.Template.Spec.ServiceAccountName, + Namespace: csv.GetNamespace(), + }, + }, + RoleRef: rbacv1.RoleRef{ + APIGroup: "rbac.authorization.k8s.io", + Kind: "ClusterRole", + Name: "system:auth-delegator", + }, + } + authDelegatorClusterRoleBinding.SetName(apiServiceName + "-system:auth-delegator") + + existingAuthDelegatorClusterRoleBinding, err := a.lister.RbacV1().ClusterRoleBindingLister().Get(authDelegatorClusterRoleBinding.GetName()) + if err == nil { + // Check if the only owners are this CSV or in this CSV's replacement chain. + if ownerutil.AdoptableLabels(existingAuthDelegatorClusterRoleBinding.GetLabels(), true, csv) { + logger.WithFields(log.Fields{"obj": "authDelegatorCRB", "labels": existingAuthDelegatorClusterRoleBinding.GetLabels()}).Debug("adopting") + if err := ownerutil.AddOwnerLabels(authDelegatorClusterRoleBinding, csv); err != nil { + return nil, err + } + } + + // Attempt an update. + if _, err := a.OpClient.UpdateClusterRoleBinding(authDelegatorClusterRoleBinding); err != nil { + logger.Warnf("could not update auth delegator clusterrolebinding %s", authDelegatorClusterRoleBinding.GetName()) + return nil, err + } + } else if k8serrors.IsNotFound(err) { + // Create the role. + if err := ownerutil.AddOwnerLabels(authDelegatorClusterRoleBinding, csv); err != nil { + return nil, err + } + _, err = a.OpClient.CreateClusterRoleBinding(authDelegatorClusterRoleBinding) + if err != nil { + log.Warnf("could not create auth delegator clusterrolebinding %s", authDelegatorClusterRoleBinding.GetName()) + return nil, err + } + } else { + return nil, err + } + + // Create RoleBinding to extension-apiserver-authentication-reader Role in the kube-system namespace. + authReaderRoleBinding := &rbacv1.RoleBinding{ + Subjects: []rbacv1.Subject{ + { + Kind: "ServiceAccount", + APIGroup: "", + Name: depSpec.Template.Spec.ServiceAccountName, + Namespace: csv.GetNamespace(), + }, + }, + RoleRef: rbacv1.RoleRef{ + APIGroup: "rbac.authorization.k8s.io", + Kind: "Role", + Name: "extension-apiserver-authentication-reader", + }, + } + authReaderRoleBinding.SetName(apiServiceName + "-auth-reader") + authReaderRoleBinding.SetNamespace("kube-system") + + existingAuthReaderRoleBinding, err := a.lister.RbacV1().RoleBindingLister().RoleBindings("kube-system").Get(authReaderRoleBinding.GetName()) + if err == nil { + // Check if the only owners are this CSV or in this CSV's replacement chain. + if ownerutil.AdoptableLabels(existingAuthReaderRoleBinding.GetLabels(), true, csv) { + logger.WithFields(log.Fields{"obj": "existingAuthReaderRB", "labels": existingAuthReaderRoleBinding.GetLabels()}).Debug("adopting") + if err := ownerutil.AddOwnerLabels(authReaderRoleBinding, csv); err != nil { + return nil, err + } + } + // Attempt an update. + if _, err := a.OpClient.UpdateRoleBinding(authReaderRoleBinding); err != nil { + logger.Warnf("could not update auth reader role binding %s", authReaderRoleBinding.GetName()) + return nil, err + } + } else if k8serrors.IsNotFound(err) { + // Create the role. + if err := ownerutil.AddOwnerLabels(authReaderRoleBinding, csv); err != nil { + return nil, err + } + _, err = a.OpClient.CreateRoleBinding(authReaderRoleBinding) + if err != nil { + log.Warnf("could not create auth reader role binding %s", authReaderRoleBinding.GetName()) + return nil, err + } + } else { + return nil, err + } + + // Update deployment with secret volume mount. + volume := corev1.Volume{ + Name: "apiservice-cert", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: secret.GetName(), + Items: []corev1.KeyToPath{ + { + Key: "tls.crt", + Path: "apiserver.crt", + }, + { + Key: "tls.key", + Path: "apiserver.key", + }, + }, + }, + }, + } + + replaced := false + for i, v := range depSpec.Template.Spec.Volumes { + if v.Name == volume.Name { + depSpec.Template.Spec.Volumes[i] = volume + replaced = true + break + } + } + if !replaced { + depSpec.Template.Spec.Volumes = append(depSpec.Template.Spec.Volumes, volume) + } + + mount := corev1.VolumeMount{ + Name: volume.Name, + MountPath: "/apiserver.local.config/certificates", + } + for i, container := range depSpec.Template.Spec.Containers { + found := false + for j, m := range container.VolumeMounts { + if m.Name == mount.Name { + found = true + break + } + + // Replace if mounting to the same location. + if m.MountPath == mount.MountPath { + container.VolumeMounts[j] = mount + found = true + break + } + } + if !found { + container.VolumeMounts = append(container.VolumeMounts, mount) + } + + depSpec.Template.Spec.Containers[i] = container + } + + // Setting the olm hash label forces a rollout and ensures that the new secret + // is used by the apiserver if not hot reloading. + depSpec.Template.ObjectMeta.SetAnnotations(map[string]string{OLMCAHashAnnotationKey: caHash}) + + exists := true + apiService, err := a.lister.APIRegistrationV1().APIServiceLister().Get(apiServiceName) + if err != nil { + if !k8serrors.IsNotFound(err) { + return nil, err + } + + exists = false + apiService = &apiregistrationv1.APIService{ + Spec: apiregistrationv1.APIServiceSpec{ + Group: desc.Group, + Version: desc.Version, + GroupPriorityMinimum: int32(2000), + VersionPriority: int32(15), + }, + } + apiService.SetName(apiServiceName) + } else { + owners := []ownerutil.Owner{csv} + + // Get replacing CSV + replaces, err := a.lister.OperatorsV1alpha1().ClusterServiceVersionLister().ClusterServiceVersions(csv.GetNamespace()).Get(csv.Spec.Replaces) + if err == nil { + owners = append(owners, replaces) + } + + // check if the APIService is adoptable + if !ownerutil.AdoptableLabels(apiService.GetLabels(), true, owners...) { + logger.WithFields(log.Fields{"obj": "apiService", "labels": apiService.GetLabels()}).Debug("adoption failed") + return nil, fmt.Errorf("pre-existing APIService %s is not adoptable", apiServiceName) + } + } + + // Add the CSV as an owner + if err := ownerutil.AddOwnerLabels(apiService, csv); err != nil { + return nil, err + } + + // update the ServiceReference + apiService.Spec.Service = &apiregistrationv1.ServiceReference{ + Namespace: service.GetNamespace(), + Name: service.GetName(), + } + + // create a fresh CA bundle + apiService.Spec.CABundle = caPEM + + // attempt a update or create + if exists { + logger.Debug("updating APIService") + _, err = a.OpClient.UpdateAPIService(apiService) + } else { + logger.Debug("creating APIService") + _, err = a.OpClient.CreateAPIService(apiService) + } + + if err != nil { + logger.Warnf("could not create or update APIService") + return nil, err + } + + return &depSpec, nil +} + +// APIServiceNameToServiceName returns the result of replacing all +// periods in the given APIService name with hyphens +func APIServiceNameToServiceName(apiServiceName string) string { + // Replace all '.'s with "-"s to convert to a DNS-1035 label + return strings.Replace(apiServiceName, ".", "-", -1) +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/olm/operator.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/olm/operator.go index 110a64cd40..ecf8fae369 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/olm/operator.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/olm/operator.go @@ -3,28 +3,47 @@ package olm import ( "errors" "fmt" + "strings" "time" - log "github.com/sirupsen/logrus" - "k8s.io/api/apps/v1" + v1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1" + "github.com/sirupsen/logrus" corev1 "k8s.io/api/core/v1" + extinf "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions" + k8serrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + utilerrors "k8s.io/apimachinery/pkg/util/errors" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/client-go/informers" "k8s.io/client-go/tools/cache" + "k8s.io/client-go/tools/record" "k8s.io/client-go/util/workqueue" + kagg "k8s.io/kube-aggregator/pkg/client/informers/externalversions" "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned" "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions" - "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/annotator" + "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/certs" "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install" + "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver" + "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/event" + index "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/index" + "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/labeler" "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient" + "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister" "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil" "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/queueinformer" + "github.com/operator-framework/operator-lifecycle-manager/pkg/metrics" ) -var ErrRequirementsNotMet = errors.New("requirements were not met") -var ErrCRDOwnerConflict = errors.New("CRD owned by another ClusterServiceVersion") +var ( + ErrRequirementsNotMet = errors.New("requirements were not met") + ErrCRDOwnerConflict = errors.New("conflicting CRD owner in namespace") + ErrAPIServiceOwnerConflict = errors.New("unable to adopt APIService") +) + +var timeNow = func() metav1.Time { return metav1.NewTime(time.Now().UTC()) } const ( FallbackWakeupInterval = 30 * time.Second @@ -32,14 +51,20 @@ const ( type Operator struct { *queueinformer.Operator - csvQueue workqueue.RateLimitingInterface - client versioned.Interface - resolver install.StrategyResolverInterface - annotator *annotator.Annotator - cleanupFunc func() + csvQueueSet *queueinformer.ResourceQueueSet + ogQueueSet *queueinformer.ResourceQueueSet + client versioned.Interface + resolver install.StrategyResolverInterface + apiReconciler resolver.APIIntersectionReconciler + lister operatorlister.OperatorLister + recorder record.EventRecorder + copyQueueIndexer *queueinformer.QueueIndexer + gcQueueIndexer *queueinformer.QueueIndexer + apiLabeler labeler.Labeler + csvIndexers map[string]cache.Indexer } -func NewOperator(crClient versioned.Interface, opClient operatorclient.ClientInterface, resolver install.StrategyResolverInterface, wakeupInterval time.Duration, annotations map[string]string, namespaces []string) (*Operator, error) { +func NewOperator(logger *logrus.Logger, crClient versioned.Interface, opClient operatorclient.ClientInterface, strategyResolver install.StrategyResolverInterface, wakeupInterval time.Duration, namespaces []string) (*Operator, error) { if wakeupInterval < 0 { wakeupInterval = FallbackWakeupInterval } @@ -47,220 +72,987 @@ func NewOperator(crClient versioned.Interface, opClient operatorclient.ClientInt namespaces = []string{metav1.NamespaceAll} } - queueOperator, err := queueinformer.NewOperatorFromClient(opClient) + queueOperator, err := queueinformer.NewOperatorFromClient(opClient, logger) + if err != nil { + return nil, err + } + eventRecorder, err := event.NewRecorder(opClient.KubernetesInterface().CoreV1().Events(metav1.NamespaceAll)) if err != nil { return nil, err } - namespaceAnnotator := annotator.NewAnnotator(queueOperator.OpClient, annotations) op := &Operator{ - Operator: queueOperator, - client: crClient, - resolver: resolver, - annotator: namespaceAnnotator, - cleanupFunc: func() { - namespaceAnnotator.CleanNamespaceAnnotations(namespaces) + Operator: queueOperator, + csvQueueSet: queueinformer.NewEmptyResourceQueueSet(), + ogQueueSet: queueinformer.NewEmptyResourceQueueSet(), + client: crClient, + resolver: strategyResolver, + apiReconciler: resolver.APIIntersectionReconcileFunc(resolver.ReconcileAPIIntersection), + lister: operatorlister.NewLister(), + recorder: eventRecorder, + apiLabeler: labeler.Func(resolver.LabelSetsFor), + csvIndexers: map[string]cache.Indexer{}, + } + + // Set up RBAC informers + roleInformer := informers.NewSharedInformerFactory(opClient.KubernetesInterface(), wakeupInterval).Rbac().V1().Roles() + roleQueueInformer := queueinformer.NewInformer( + workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "roles"), + roleInformer.Informer(), + op.syncObject, + nil, + "roles", + metrics.NewMetricsNil(), + logger, + ) + op.RegisterQueueInformer(roleQueueInformer) + op.lister.RbacV1().RegisterRoleLister(metav1.NamespaceAll, roleInformer.Lister()) + + roleBindingInformer := informers.NewSharedInformerFactory(opClient.KubernetesInterface(), wakeupInterval).Rbac().V1().RoleBindings() + roleBindingQueueInformer := queueinformer.NewInformer( + workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "rolebindings"), + roleBindingInformer.Informer(), + op.syncObject, + nil, + "rolebindings", + metrics.NewMetricsNil(), + logger, + ) + op.RegisterQueueInformer(roleBindingQueueInformer) + op.lister.RbacV1().RegisterRoleBindingLister(metav1.NamespaceAll, roleBindingInformer.Lister()) + + clusterRoleInformer := informers.NewSharedInformerFactory(opClient.KubernetesInterface(), wakeupInterval).Rbac().V1().ClusterRoles() + clusterRoleQueueInformer := queueinformer.NewInformer( + workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "clusterroles"), + clusterRoleInformer.Informer(), + op.syncObject, + nil, + "clusterroles", + metrics.NewMetricsNil(), + logger, + ) + op.RegisterQueueInformer(clusterRoleQueueInformer) + op.lister.RbacV1().RegisterClusterRoleLister(clusterRoleInformer.Lister()) + + clusterRoleBindingInformer := informers.NewSharedInformerFactory(opClient.KubernetesInterface(), wakeupInterval).Rbac().V1().ClusterRoleBindings() + clusterRoleBindingQueueInformer := queueinformer.NewInformer( + workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "clusterrolebindings"), + clusterRoleBindingInformer.Informer(), + op.syncObject, + nil, + "clusterrolebindings", + metrics.NewMetricsNil(), + logger, + ) + op.lister.RbacV1().RegisterClusterRoleBindingLister(clusterRoleBindingInformer.Lister()) + op.RegisterQueueInformer(clusterRoleBindingQueueInformer) + + // register namespace queueinformer + namespaceInformer := informers.NewSharedInformerFactory(opClient.KubernetesInterface(), wakeupInterval).Core().V1().Namespaces() + namespaceQueueInformer := queueinformer.NewInformer( + workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "namespaces"), + namespaceInformer.Informer(), + op.syncObject, + &cache.ResourceEventHandlerFuncs{ + DeleteFunc: op.namespaceAddedOrRemoved, + AddFunc: op.namespaceAddedOrRemoved, + }, + "namespaces", + metrics.NewMetricsNil(), + logger, + ) + op.RegisterQueueInformer(namespaceQueueInformer) + op.lister.CoreV1().RegisterNamespaceLister(namespaceInformer.Lister()) + + // Register APIService QueueInformer + apiServiceInformer := kagg.NewSharedInformerFactory(opClient.ApiregistrationV1Interface(), wakeupInterval).Apiregistration().V1().APIServices() + op.RegisterQueueInformer(queueinformer.NewInformer( + workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "apiservices"), + apiServiceInformer.Informer(), + op.syncObject, + &cache.ResourceEventHandlerFuncs{ + DeleteFunc: op.handleDeletion, }, + "apiservices", + metrics.NewMetricsNil(), + logger, + )) + op.lister.APIRegistrationV1().RegisterAPIServiceLister(apiServiceInformer.Lister()) + + // Register CustomResourceDefinition QueueInformer + customResourceDefinitionInformer := extinf.NewSharedInformerFactory(opClient.ApiextensionsV1beta1Interface(), wakeupInterval).Apiextensions().V1beta1().CustomResourceDefinitions() + op.RegisterQueueInformer(queueinformer.NewInformer( + workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "customresourcedefinitions"), + customResourceDefinitionInformer.Informer(), + op.syncObject, + &cache.ResourceEventHandlerFuncs{ + DeleteFunc: op.handleDeletion, + }, + "customresourcedefinitions", + metrics.NewMetricsNil(), + logger, + )) + op.lister.APIExtensionsV1beta1().RegisterCustomResourceDefinitionLister(customResourceDefinitionInformer.Lister()) + + // Register Secret QueueInformer + secretInformer := informers.NewSharedInformerFactory(opClient.KubernetesInterface(), wakeupInterval).Core().V1().Secrets() + op.RegisterQueueInformer(queueinformer.NewInformer( + workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "secrets"), + secretInformer.Informer(), + op.syncObject, + &cache.ResourceEventHandlerFuncs{ + DeleteFunc: op.handleDeletion, + }, + "secrets", + metrics.NewMetricsNil(), + logger, + )) + op.lister.CoreV1().RegisterSecretLister(metav1.NamespaceAll, secretInformer.Lister()) + + // Register Service QueueInformer + serviceInformer := informers.NewSharedInformerFactory(opClient.KubernetesInterface(), wakeupInterval).Core().V1().Services() + op.RegisterQueueInformer(queueinformer.NewInformer( + workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "services"), + serviceInformer.Informer(), + op.syncObject, + &cache.ResourceEventHandlerFuncs{ + DeleteFunc: op.handleDeletion, + }, + "services", + metrics.NewMetricsNil(), + logger, + )) + op.lister.CoreV1().RegisterServiceLister(metav1.NamespaceAll, serviceInformer.Lister()) + + // Register ServiceAccount QueueInformer + serviceAccountInformer := informers.NewSharedInformerFactory(opClient.KubernetesInterface(), wakeupInterval).Core().V1().ServiceAccounts() + op.RegisterQueueInformer(queueinformer.NewInformer( + workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "serviceaccounts"), + serviceAccountInformer.Informer(), + op.syncObject, + &cache.ResourceEventHandlerFuncs{ + DeleteFunc: op.handleDeletion, + }, + "serviceaccounts", + metrics.NewMetricsNil(), + logger, + )) + op.lister.CoreV1().RegisterServiceAccountLister(metav1.NamespaceAll, serviceAccountInformer.Lister()) + + // csvInformers for each namespace all use the same backing queue keys are namespaced + csvHandlers := &cache.ResourceEventHandlerFuncs{ + DeleteFunc: op.handleClusterServiceVersionDeletion, } + for _, namespace := range namespaces { + logger.WithField("namespace", namespace).Infof("watching CSVs") + sharedInformerFactory := externalversions.NewSharedInformerFactoryWithOptions(crClient, wakeupInterval, externalversions.WithNamespace(namespace)) + csvInformer := sharedInformerFactory.Operators().V1alpha1().ClusterServiceVersions() + op.lister.OperatorsV1alpha1().RegisterClusterServiceVersionLister(namespace, csvInformer.Lister()) - // if watching all namespaces, set up a watch to annotate new namespaces - if len(namespaces) == 1 && namespaces[0] == metav1.NamespaceAll { - log.Debug("watching all namespaces, setting up queue") - namespaceInformer := informers.NewSharedInformerFactory(queueOperator.OpClient.KubernetesInterface(), wakeupInterval).Core().V1().Namespaces().Informer() - queueInformer := queueinformer.NewInformer( - workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "namespaces"), - namespaceInformer, - op.annotateNamespace, - nil, - "namespace", - ) - op.RegisterQueueInformer(queueInformer) + // Register queue and QueueInformer + queueName := fmt.Sprintf("%s/clusterserviceversions", namespace) + csvQueue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), queueName) + csvQueueInformer := queueinformer.NewInformer(csvQueue, csvInformer.Informer(), op.syncClusterServiceVersion, csvHandlers, queueName, metrics.NewMetricsCSV(op.lister.OperatorsV1alpha1().ClusterServiceVersionLister()), logger) + op.RegisterQueueInformer(csvQueueInformer) + op.csvQueueSet.Set(namespace, csvQueue) + + csvInformer.Informer().AddIndexers(cache.Indexers{index.MetaLabelIndexFuncKey: index.MetaLabelIndexFunc}) + op.csvIndexers[namespace] = csvInformer.Informer().GetIndexer() } - // annotate namespaces that ALM operator manages - if err := namespaceAnnotator.AnnotateNamespaces(namespaces); err != nil { - return nil, err + // Register separate queue for copying csvs + csvCopyQueue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "csvCopy") + csvQueueIndexer := queueinformer.NewQueueIndexer(csvCopyQueue, op.csvIndexers, op.syncCopyCSV, "csvCopy", logger, metrics.NewMetricsNil()) + op.RegisterQueueIndexer(csvQueueIndexer) + op.copyQueueIndexer = csvQueueIndexer + + // Register separate queue for gcing csvs + csvGCQueue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "csvGC") + csvGCQueueIndexer := queueinformer.NewQueueIndexer(csvGCQueue, op.csvIndexers, op.syncGcCsv, "csvGC", logger, metrics.NewMetricsNil()) + op.RegisterQueueIndexer(csvGCQueueIndexer) + op.gcQueueIndexer = csvGCQueueIndexer + + // Set up watch on deployments + depHandlers := &cache.ResourceEventHandlerFuncs{ + // TODO: pass closure that forgets queue item after calling custom deletion handler. + DeleteFunc: op.handleDeletion, + } + for _, namespace := range namespaces { + logger.WithField("namespace", namespace).Infof("watching deployments") + depInformer := informers.NewSharedInformerFactoryWithOptions(opClient.KubernetesInterface(), wakeupInterval, informers.WithNamespace(namespace)).Apps().V1().Deployments() + op.lister.AppsV1().RegisterDeploymentLister(namespace, depInformer.Lister()) + + // Register queue and QueueInformer + queueName := fmt.Sprintf("%s/csv-deployments", namespace) + depQueue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), queueName) + depQueueInformer := queueinformer.NewInformer(depQueue, depInformer.Informer(), op.syncObject, depHandlers, queueName, metrics.NewMetricsNil(), logger) + op.RegisterQueueInformer(depQueueInformer) } - // set up watch on CSVs - csvInformers := []cache.SharedIndexInformer{} + // Create an informer for the operator group for _, namespace := range namespaces { - log.Debugf("watching for CSVs in namespace %s", namespace) + logger.WithField("namespace", namespace).Infof("watching OperatorGroups") sharedInformerFactory := externalversions.NewSharedInformerFactoryWithOptions(crClient, wakeupInterval, externalversions.WithNamespace(namespace)) - informer := sharedInformerFactory.Operators().V1alpha1().ClusterServiceVersions().Informer() - csvInformers = append(csvInformers, informer) + operatorGroupInformer := sharedInformerFactory.Operators().V1().OperatorGroups() + op.lister.OperatorsV1().RegisterOperatorGroupLister(namespace, operatorGroupInformer.Lister()) + + // Register queue and QueueInformer + queueName := fmt.Sprintf("%s/operatorgroups", namespace) + operatorGroupQueue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), queueName) + operatorGroupQueueInformer := queueinformer.NewInformer(operatorGroupQueue, operatorGroupInformer.Informer(), op.syncOperatorGroups, nil, queueName, metrics.NewMetricsNil(), logger) + op.RegisterQueueInformer(operatorGroupQueueInformer) + op.ogQueueSet.Set(namespace, operatorGroupQueue) } - // csvInformers for each namespace all use the same backing queue - // queue keys are namespaced - csvQueue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "clusterserviceversions") - queueInformers := queueinformer.New( - csvQueue, - csvInformers, - op.syncClusterServiceVersion, - nil, - "csv", - ) - for _, informer := range queueInformers { - op.RegisterQueueInformer(informer) + return op, nil +} + +func (a *Operator) syncObject(obj interface{}) (syncError error) { + // Assert as metav1.Object + metaObj, ok := obj.(metav1.Object) + if !ok { + syncError = errors.New("object sync: casting to metav1.Object failed") + a.Log.Warn(syncError.Error()) + return } - op.csvQueue = csvQueue + logger := a.Log.WithFields(logrus.Fields{ + "name": metaObj.GetName(), + "namespace": metaObj.GetNamespace(), + "self": metaObj.GetSelfLink(), + }) - // set up watch on deployments - depInformers := []cache.SharedIndexInformer{} - for _, namespace := range namespaces { - log.Debugf("watching deployments in namespace %s", namespace) - informer := informers.NewSharedInformerFactoryWithOptions(opClient.KubernetesInterface(), wakeupInterval, informers.WithNamespace(namespace)).Apps().V1().Deployments().Informer() - depInformers = append(depInformers, informer) + // Requeue all owner CSVs + if ownerutil.IsOwnedByKind(metaObj, v1alpha1.ClusterServiceVersionKind) { + logger.Debug("requeueing owner csvs") + a.requeueOwnerCSVs(metaObj) } - depQueue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "csv-deployments") - depQueueInformers := queueinformer.New( - depQueue, - depInformers, - op.syncDeployment, - nil, - "deployment", - ) - for _, informer := range depQueueInformers { - op.RegisterQueueInformer(informer) + // Requeues objects that can't have ownerrefs (cluster -> namespace, cross-namespace) + if ownerutil.IsOwnedByKindLabel(metaObj, v1alpha1.ClusterServiceVersionKind) { + logger.Debug("requeueing owner csvs") + a.requeueOwnerCSVs(metaObj) } - return op, nil -} -func (a *Operator) Cleanup() { - a.cleanupFunc() + // Requeue CSVs with provided and required labels (for CRDs) + if labelSets, err := a.apiLabeler.LabelSetsFor(metaObj); err != nil { + logger.WithError(err).Warn("couldn't create label set") + } else if len(labelSets) > 0 { + logger.Debug("requeueing providing/requiring csvs") + a.requeueCSVsByLabelSet(logger, labelSets...) + } + + return nil } -func (a *Operator) requeueCSV(name, namespace string) { - // we can build the key directly, will need to change if queue uses different key scheme - key := fmt.Sprintf("%s/%s", namespace, name) - a.csvQueue.AddRateLimited(key) +func (a *Operator) namespaceAddedOrRemoved(obj interface{}) { + // Check to see if any operator groups are associated with this namespace + namespace, ok := obj.(*corev1.Namespace) + if !ok { + return + } + + logger := a.Log.WithFields(logrus.Fields{ + "name": namespace.GetName(), + }) + + operatorGroupList, err := a.lister.OperatorsV1().OperatorGroupLister().OperatorGroups(metav1.NamespaceAll).List(labels.Everything()) + if err != nil { + logger.WithError(err).Warn("lister failed") + return + } + + for _, group := range operatorGroupList { + if resolver.NewNamespaceSet(group.Status.Namespaces).Contains(namespace.GetName()) { + if err := a.ogQueueSet.Requeue(group.Name, group.Namespace); err != nil { + logger.WithError(err).Warn("error requeuing operatorgroup") + } + } + } return } -func (a *Operator) syncDeployment(obj interface{}) (syncError error) { - deployment, ok := obj.(*v1.Deployment) +func (a *Operator) handleClusterServiceVersionDeletion(obj interface{}) { + clusterServiceVersion, ok := obj.(*v1alpha1.ClusterServiceVersion) + if !ok { + tombstone, ok := obj.(cache.DeletedFinalStateUnknown) + if !ok { + utilruntime.HandleError(fmt.Errorf("couldn't get object from tombstone %#v", obj)) + return + } + + clusterServiceVersion, ok = tombstone.Obj.(*v1alpha1.ClusterServiceVersion) + if !ok { + utilruntime.HandleError(fmt.Errorf("tombstone contained object that is not a ClusterServiceVersion %#v", obj)) + return + } + } + + logger := a.Log.WithFields(logrus.Fields{ + "id": queueinformer.NewLoopID(), + "csv": clusterServiceVersion.GetName(), + "namespace": clusterServiceVersion.GetNamespace(), + "phase": clusterServiceVersion.Status.Phase, + }) + + defer func(csv v1alpha1.ClusterServiceVersion) { + logger.Debug("removing csv from queue set") + a.csvQueueSet.Remove(csv.GetName(), csv.GetNamespace()) + + // Requeue all OperatorGroups in the namespace + logger.Debug("requeueing operatorgroups in namespace") + operatorGroups, err := a.lister.OperatorsV1().OperatorGroupLister().OperatorGroups(csv.GetNamespace()).List(labels.Everything()) + if err != nil { + logger.WithError(err).Warnf("an error occurred while listing operatorgroups to requeue after csv deletion") + return + } + + for _, operatorGroup := range operatorGroups { + logger := logger.WithField("operatorgroup", operatorGroup.GetName()) + logger.Debug("requeueing") + if err := a.ogQueueSet.Requeue(operatorGroup.GetName(), operatorGroup.GetNamespace()); err != nil { + logger.WithError(err).Debug("error requeueing operatorgroup") + } + } + }(*clusterServiceVersion) + + targetNamespaces, ok := clusterServiceVersion.Annotations[v1.OperatorGroupTargetsAnnotationKey] + if !ok { + logger.Debug("missing target namespaces annotation on csv") + return + } + + operatorNamespace, ok := clusterServiceVersion.Annotations[v1.OperatorGroupNamespaceAnnotationKey] + if !ok { + logger.Debug("missing operator namespace annotation on csv") + return + } + + if _, ok = clusterServiceVersion.Annotations[v1.OperatorGroupAnnotationKey]; !ok { + logger.Debug("missing operatorgroup name annotation on csv") + return + } + + if clusterServiceVersion.IsCopied() { + logger.Debug("deleted csv is copied. skipping additional cleanup steps") + return + } + + logger.Info("gcing children") + namespaces := []string{} + if targetNamespaces == "" { + namespaceList, err := a.OpClient.KubernetesInterface().CoreV1().Namespaces().List(metav1.ListOptions{}) + if err != nil { + logger.WithError(err).Warn("cannot list all namespaces to requeue child csvs for deletion") + return + } + for _, namespace := range namespaceList.Items { + namespaces = append(namespaces, namespace.GetName()) + } + } else { + namespaces = strings.Split(targetNamespaces, ",") + } + for _, namespace := range namespaces { + if namespace != operatorNamespace { + logger.WithField("targetNamespace", namespace).Debug("requeueing child csv for deletion") + a.gcQueueIndexer.Add(fmt.Sprintf("%s/%s", namespace, clusterServiceVersion.GetName())) + } + } + + for _, desc := range clusterServiceVersion.Spec.APIServiceDefinitions.Owned { + apiServiceName := fmt.Sprintf("%s.%s", desc.Version, desc.Group) + fetched, err := a.lister.APIRegistrationV1().APIServiceLister().Get(apiServiceName) + if k8serrors.IsNotFound(err) { + continue + } + if err != nil { + logger.WithError(err).Warn("api service get failure") + continue + } + apiServiceLabels := fetched.GetLabels() + if clusterServiceVersion.GetName() == apiServiceLabels[ownerutil.OwnerKey] && clusterServiceVersion.GetNamespace() == apiServiceLabels[ownerutil.OwnerNamespaceKey] { + logger.Infof("gcing api service %v", apiServiceName) + err := a.OpClient.DeleteAPIService(apiServiceName, &metav1.DeleteOptions{}) + if err != nil { + logger.WithError(err).Warn("cannot delete orphaned api service") + } + } + } +} + +func (a *Operator) removeDanglingChildCSVs(csv *v1alpha1.ClusterServiceVersion) error { + logger := a.Log.WithFields(logrus.Fields{ + "id": queueinformer.NewLoopID(), + "csv": csv.GetName(), + "namespace": csv.GetNamespace(), + "phase": csv.Status.Phase, + "labels": csv.GetLabels(), + "annotations": csv.GetAnnotations(), + }) + + if !csv.IsCopied() { + logger.Debug("removeDanglingChild called on a parent. this is a no-op but should be avoided.") + return nil + } + + operatorNamespace, ok := csv.Annotations[v1.OperatorGroupNamespaceAnnotationKey] if !ok { - log.Debugf("wrong type: %#v", obj) - return fmt.Errorf("casting Deployment failed") + logger.Debug("missing operator namespace annotation on copied CSV") + return a.deleteChild(csv, logger) + } + + logger = logger.WithField("parentNamespace", operatorNamespace) + parent, err := a.lister.OperatorsV1alpha1().ClusterServiceVersionLister().ClusterServiceVersions(operatorNamespace).Get(csv.GetName()) + if k8serrors.IsNotFound(err) || k8serrors.IsGone(err) || parent == nil { + logger.Debug("deleting copied CSV since parent is missing") + return a.deleteChild(csv, logger) + } + + if parent.Status.Phase == v1alpha1.CSVPhaseFailed && parent.Status.Reason == v1alpha1.CSVReasonInterOperatorGroupOwnerConflict { + logger.Debug("deleting copied CSV since parent has intersecting operatorgroup conflict") + return a.deleteChild(csv, logger) } - if ownerutil.IsOwnedByKind(deployment, v1alpha1.ClusterServiceVersionKind) { - oref := ownerutil.GetOwnerByKind(deployment, v1alpha1.ClusterServiceVersionKind) - a.requeueCSV(oref.Name, deployment.GetNamespace()) + + if annotations := parent.GetAnnotations(); annotations != nil { + if !resolver.NewNamespaceSetFromString(annotations[v1.OperatorGroupTargetsAnnotationKey]).Contains(csv.GetNamespace()) { + logger.WithField("parentTargets", annotations[v1.OperatorGroupTargetsAnnotationKey]). + Debug("deleting copied CSV since parent no longer lists this as a target namespace") + return a.deleteChild(csv, logger) + } } + return nil } +func (a *Operator) deleteChild(csv *v1alpha1.ClusterServiceVersion, logger *logrus.Entry) error { + logger.Debug("gcing csv") + return a.client.OperatorsV1alpha1().ClusterServiceVersions(csv.GetNamespace()).Delete(csv.GetName(), metav1.NewDeleteOptions(0)) +} + // syncClusterServiceVersion is the method that gets called when we see a CSV event in the cluster func (a *Operator) syncClusterServiceVersion(obj interface{}) (syncError error) { clusterServiceVersion, ok := obj.(*v1alpha1.ClusterServiceVersion) if !ok { - log.Debugf("wrong type: %#v", obj) + a.Log.Debugf("wrong type: %#v", obj) return fmt.Errorf("casting ClusterServiceVersion failed") } - logger := log.WithFields(log.Fields{ + + logger := a.Log.WithFields(logrus.Fields{ + "id": queueinformer.NewLoopID(), "csv": clusterServiceVersion.GetName(), "namespace": clusterServiceVersion.GetNamespace(), "phase": clusterServiceVersion.Status.Phase, }) - logger.Info("syncing") + logger.Debug("syncing CSV") outCSV, syncError := a.transitionCSVState(*clusterServiceVersion) - // no changes in status, don't update - if outCSV.Status.Phase == clusterServiceVersion.Status.Phase && outCSV.Status.Reason == clusterServiceVersion.Status.Reason && outCSV.Status.Message == clusterServiceVersion.Status.Message { + if outCSV == nil { return } - // Update CSV with status of transition. Log errors if we can't write them to the status. - _, err := a.client.OperatorsV1alpha1().ClusterServiceVersions(clusterServiceVersion.GetNamespace()).UpdateStatus(outCSV) - if err != nil { - updateErr := errors.New("error updating ClusterServiceVersion status: " + err.Error()) - if syncError == nil { - logger.Info(updateErr) - return updateErr + // status changed, update CSV + if !(outCSV.Status.LastUpdateTime == clusterServiceVersion.Status.LastUpdateTime && + outCSV.Status.Phase == clusterServiceVersion.Status.Phase && + outCSV.Status.Reason == clusterServiceVersion.Status.Reason && + outCSV.Status.Message == clusterServiceVersion.Status.Message) { + + // Update CSV with status of transition. Log errors if we can't write them to the status. + _, err := a.client.OperatorsV1alpha1().ClusterServiceVersions(outCSV.GetNamespace()).UpdateStatus(outCSV) + if err != nil { + updateErr := errors.New("error updating ClusterServiceVersion status: " + err.Error()) + if syncError == nil { + logger.Info(updateErr) + return updateErr + } + syncError = fmt.Errorf("error transitioning ClusterServiceVersion: %s and error updating CSV status: %s", syncError, updateErr) } - syncError = fmt.Errorf("error transitioning ClusterServiceVersion: %s and error updating CSV status: %s", syncError, updateErr) } + + a.copyQueueIndexer.Enqueue(outCSV) + return } -// transitionCSVState moves the CSV status state machine along based on the current value and the current cluster -// state. +func (a *Operator) syncCopyCSV(obj interface{}) (syncError error) { + clusterServiceVersion, ok := obj.(*v1alpha1.ClusterServiceVersion) + if !ok { + a.Log.Debugf("wrong type: %#v", obj) + return fmt.Errorf("casting ClusterServiceVersion failed") + } + + logger := a.Log.WithFields(logrus.Fields{ + "id": queueinformer.NewLoopID(), + "csv": clusterServiceVersion.GetName(), + "namespace": clusterServiceVersion.GetNamespace(), + "phase": clusterServiceVersion.Status.Phase, + }) + + logger.Debug("copying CSV") + + if clusterServiceVersion.IsUncopiable() { + logger.Debug("CSV uncopiable") + return + } + + operatorGroup := a.operatorGroupFromAnnotations(logger, clusterServiceVersion) + if operatorGroup == nil { + logger.WithField("reason", "no operatorgroup found for active CSV").Debug("skipping CSV resource copy to target namespaces") + return + } + + if len(operatorGroup.Status.Namespaces) == 1 && operatorGroup.Status.Namespaces[0] == operatorGroup.GetNamespace() { + logger.Debug("skipping copy for OwnNamespace operatorgroup") + return + } + + logger.WithFields(logrus.Fields{ + "targetNamespaces": strings.Join(operatorGroup.Status.Namespaces, ","), + }).Debug("copying csv to targets") + + // Check if we need to do any copying / annotation for the operatorgroup + if err := a.ensureCSVsInNamespaces(clusterServiceVersion, operatorGroup, resolver.NewNamespaceSet(operatorGroup.Status.Namespaces)); err != nil { + logger.WithError(err).Info("couldn't copy CSV to target namespaces") + syncError = err + } + + // Ensure operator has access to targetnamespaces + if err := a.ensureRBACInTargetNamespace(clusterServiceVersion, operatorGroup); err != nil { + logger.WithError(err).Info("couldn't ensure RBAC in target namespaces") + syncError = err + } + + // Ensure cluster roles exist for using provided apis + if err := a.ensureClusterRolesForCSV(clusterServiceVersion, operatorGroup); err != nil { + logger.WithError(err).Info("couldn't ensure clusterroles for provided api types") + syncError = err + } + return +} + +func (a *Operator) syncGcCsv(obj interface{}) (syncError error) { + clusterServiceVersion, ok := obj.(*v1alpha1.ClusterServiceVersion) + if !ok { + a.Log.Debugf("wrong type: %#v", obj) + return fmt.Errorf("casting ClusterServiceVersion failed") + } + if clusterServiceVersion.IsCopied() { + syncError = a.removeDanglingChildCSVs(clusterServiceVersion) + return + } + return +} + +// operatorGroupFromAnnotations returns the OperatorGroup for the CSV only if the CSV is active one in the group +func (a *Operator) operatorGroupFromAnnotations(logger *logrus.Entry, csv *v1alpha1.ClusterServiceVersion) *v1.OperatorGroup { + annotations := csv.GetAnnotations() + + // Not part of a group yet + if annotations == nil { + logger.Info("not part of any operatorgroup, no annotations") + return nil + } + + // Not in the OperatorGroup namespace + if annotations[v1.OperatorGroupNamespaceAnnotationKey] != csv.GetNamespace() { + logger.Info("not in operatorgroup namespace") + return nil + } + + operatorGroupName, ok := annotations[v1.OperatorGroupAnnotationKey] + + // No OperatorGroup annotation + if !ok { + logger.Info("no olm.operatorGroup annotation") + return nil + } + + logger = logger.WithField("operatorgroup", operatorGroupName) + + operatorGroup, err := a.lister.OperatorsV1().OperatorGroupLister().OperatorGroups(csv.GetNamespace()).Get(operatorGroupName) + // OperatorGroup not found + if err != nil { + logger.Info("operatorgroup not found") + return nil + } + + targets, ok := annotations[v1.OperatorGroupTargetsAnnotationKey] + + // No target annotation + if !ok { + logger.Info("no olm.targetNamespaces annotation") + return nil + } + + // Target namespaces don't match + if targets != strings.Join(operatorGroup.Status.Namespaces, ",") { + logger.Info("olm.targetNamespaces annotation doesn't match operatorgroup status") + return nil + } + + return operatorGroup +} + +func (a *Operator) operatorGroupForCSV(csv *v1alpha1.ClusterServiceVersion, logger *logrus.Entry) (*v1.OperatorGroup, error) { + now := timeNow() + + // Attempt to associate an OperatorGroup with the CSV. + operatorGroups, err := a.client.OperatorsV1().OperatorGroups(csv.GetNamespace()).List(metav1.ListOptions{}) + if err != nil { + logger.Errorf("error occurred while attempting to associate csv with operatorgroup") + return nil, err + } + var operatorGroup *v1.OperatorGroup + + switch len(operatorGroups.Items) { + case 0: + err = fmt.Errorf("csv in namespace with no operatorgroups") + logger.Warn(err) + csv.SetPhaseWithEvent(v1alpha1.CSVPhaseFailed, v1alpha1.CSVReasonNoOperatorGroup, err.Error(), now, a.recorder) + return nil, err + case 1: + operatorGroup = &operatorGroups.Items[0] + logger = logger.WithField("opgroup", operatorGroup.GetName()) + if a.operatorGroupAnnotationsDiffer(&csv.ObjectMeta, operatorGroup) { + a.setOperatorGroupAnnotations(&csv.ObjectMeta, operatorGroup, true) + if _, err := a.client.OperatorsV1alpha1().ClusterServiceVersions(csv.GetNamespace()).Update(csv); err != nil { + logger.WithError(err).Warn("error adding operatorgroup annotations") + return nil, err + } + return nil, nil + } + logger.Info("csv in operatorgroup") + return operatorGroup, nil + default: + err = fmt.Errorf("csv created in namespace with multiple operatorgroups, can't pick one automatically") + logger.WithError(err).Warn("csv failed to become an operatorgroup member") + if csv.Status.Reason != v1alpha1.CSVReasonTooManyOperatorGroups { + csv.SetPhaseWithEvent(v1alpha1.CSVPhaseFailed, v1alpha1.CSVReasonTooManyOperatorGroups, err.Error(), now, a.recorder) + } + return nil, err + } +} + +// transitionCSVState moves the CSV status state machine along based on the current value and the current cluster state. func (a *Operator) transitionCSVState(in v1alpha1.ClusterServiceVersion) (out *v1alpha1.ClusterServiceVersion, syncError error) { - logger := log.WithFields(log.Fields{ + logger := a.Log.WithFields(logrus.Fields{ + "id": queueinformer.NewLoopID(), "csv": in.GetName(), "namespace": in.GetNamespace(), "phase": in.Status.Phase, }) out = in.DeepCopy() + now := timeNow() - // check if the current CSV is being replaced, return with replacing status if so + if out.IsCopied() { + logger.Debug("skipping copied csv transition, schedule for gc check") + a.gcQueueIndexer.Enqueue(out) + return + } + + operatorSurface, err := resolver.NewOperatorFromCSV(out) + if err != nil { + // TODO: Add failure status to CSV + syncError = err + return + } + + // Ensure required and provided API labels + if labelSets, err := a.apiLabeler.LabelSetsFor(operatorSurface); err != nil { + logger.WithError(err).Warn("couldn't create label set") + } else if len(labelSets) > 0 { + updated, err := a.ensureLabels(out, labelSets...) + if err != nil { + logger.WithError(err).Warn("issue ensuring csv api labels") + syncError = err + return + } + // Update the underlying value of out to preserve changes + *out = *updated + } + + // Check if the current CSV is being replaced, return with replacing status if so if err := a.checkReplacementsAndUpdateStatus(out); err != nil { - logger.WithField("err", err).Info("replacement check") + logger.WithError(err).Info("replacement check") return } + // Verify CSV operatorgroup (and update annotations if needed) + operatorGroup, err := a.operatorGroupForCSV(out, logger) + if operatorGroup == nil { + // when err is nil, we still want to exit, but we don't want to re-add the csv ratelimited to the queue + syncError = err + logger.WithError(err).Info("operatorgroup incorrect") + return + } + + if err := a.ensureDeploymentAnnotations(logger, out); err != nil { + return nil, err + } + + modeSet, err := v1alpha1.NewInstallModeSet(out.Spec.InstallModes) + if err != nil { + syncError = err + logger.WithError(err).Warn("csv has invalid installmodes") + out.SetPhaseWithEventIfChanged(v1alpha1.CSVPhaseFailed, v1alpha1.CSVReasonInvalidInstallModes, syncError.Error(), now, a.recorder) + return + } + + // Check if the CSV supports its operatorgroup's selected namespaces + targets, ok := out.GetAnnotations()[v1.OperatorGroupTargetsAnnotationKey] + if ok { + namespaces := strings.Split(targets, ",") + + if err := modeSet.Supports(out.GetNamespace(), namespaces); err != nil { + logger.WithField("reason", err.Error()).Info("installmodeset does not support operatorgroups namespace selection") + out.SetPhaseWithEventIfChanged(v1alpha1.CSVPhaseFailed, v1alpha1.CSVReasonUnsupportedOperatorGroup, err.Error(), now, a.recorder) + return + } + } else { + logger.Info("csv missing olm.targetNamespaces annotation") + out.SetPhaseWithEventIfChanged(v1alpha1.CSVPhaseFailed, v1alpha1.CSVReasonNoTargetNamespaces, "csv missing olm.targetNamespaces annotation", now, a.recorder) + return + } + + // Check for intersecting provided APIs in intersecting OperatorGroups + options := metav1.ListOptions{ + FieldSelector: fmt.Sprintf("metadata.name!=%s,metadata.namespace!=%s", operatorGroup.GetName(), operatorGroup.GetNamespace()), + } + otherGroups, err := a.client.OperatorsV1().OperatorGroups(metav1.NamespaceAll).List(options) + + groupSurface := resolver.NewOperatorGroup(operatorGroup) + otherGroupSurfaces := resolver.NewOperatorGroupSurfaces(otherGroups.Items...) + providedAPIs := operatorSurface.ProvidedAPIs().StripPlural() + + switch result := a.apiReconciler.Reconcile(providedAPIs, groupSurface, otherGroupSurfaces...); { + case operatorGroup.Spec.StaticProvidedAPIs && (result == resolver.AddAPIs || result == resolver.RemoveAPIs): + // Transition the CSV to FAILED with status reason "CannotModifyStaticOperatorGroupProvidedAPIs" + if out.Status.Reason != v1alpha1.CSVReasonInterOperatorGroupOwnerConflict { + logger.WithField("apis", providedAPIs).Warn("cannot modify provided apis of static provided api operatorgroup") + out.SetPhaseWithEvent(v1alpha1.CSVPhaseFailed, v1alpha1.CSVReasonCannotModifyStaticOperatorGroupProvidedAPIs, "static provided api operatorgroup cannot be modified by these apis", now, a.recorder) + a.cleanupCSVDeployments(logger, out) + } + return + case result == resolver.APIConflict: + // Transition the CSV to FAILED with status reason "InterOperatorGroupOwnerConflict" + if out.Status.Reason != v1alpha1.CSVReasonInterOperatorGroupOwnerConflict { + logger.WithField("apis", providedAPIs).Warn("intersecting operatorgroups provide the same apis") + out.SetPhaseWithEvent(v1alpha1.CSVPhaseFailed, v1alpha1.CSVReasonInterOperatorGroupOwnerConflict, "intersecting operatorgroups provide the same apis", now, a.recorder) + a.cleanupCSVDeployments(logger, out) + } + return + case result == resolver.AddAPIs: + // Add the CSV's provided APIs to its OperatorGroup's annotation + logger.WithField("apis", providedAPIs).Debug("adding csv provided apis to operatorgroup") + union := groupSurface.ProvidedAPIs().Union(providedAPIs) + unionedAnnotations := operatorGroup.GetAnnotations() + if unionedAnnotations == nil { + unionedAnnotations = make(map[string]string) + } + unionedAnnotations[v1.OperatorGroupProvidedAPIsAnnotationKey] = union.String() + operatorGroup.SetAnnotations(unionedAnnotations) + if _, err := a.client.OperatorsV1().OperatorGroups(operatorGroup.GetNamespace()).Update(operatorGroup); err != nil && !k8serrors.IsNotFound(err) { + syncError = fmt.Errorf("could not update operatorgroups %s annotation: %v", v1.OperatorGroupProvidedAPIsAnnotationKey, err) + } + a.csvQueueSet.Requeue(out.GetName(), out.GetNamespace()) + return + case result == resolver.RemoveAPIs: + // Remove the CSV's provided APIs from its OperatorGroup's annotation + logger.WithField("apis", providedAPIs).Debug("removing csv provided apis from operatorgroup") + difference := groupSurface.ProvidedAPIs().Difference(providedAPIs) + if diffedAnnotations := operatorGroup.GetAnnotations(); diffedAnnotations != nil { + diffedAnnotations[v1.OperatorGroupProvidedAPIsAnnotationKey] = difference.String() + operatorGroup.SetAnnotations(diffedAnnotations) + if _, err := a.client.OperatorsV1().OperatorGroups(operatorGroup.GetNamespace()).Update(operatorGroup); err != nil && !k8serrors.IsNotFound(err) { + syncError = fmt.Errorf("could not update operatorgroups %s annotation: %v", v1.OperatorGroupProvidedAPIsAnnotationKey, err) + } + } + a.csvQueueSet.Requeue(out.GetName(), out.GetNamespace()) + return + default: + logger.WithField("apis", providedAPIs).Debug("no intersecting operatorgroups provide the same apis") + } + switch out.Status.Phase { case v1alpha1.CSVPhaseNone: - logger.Infof("scheduling ClusterServiceVersion for requirement verification") - out.SetPhase(v1alpha1.CSVPhasePending, v1alpha1.CSVReasonRequirementsUnknown, "requirements not yet checked") + logger.Info("scheduling ClusterServiceVersion for requirement verification") + out.SetPhaseWithEvent(v1alpha1.CSVPhasePending, v1alpha1.CSVReasonRequirementsUnknown, "requirements not yet checked", now, a.recorder) case v1alpha1.CSVPhasePending: - met, statuses := a.requirementStatus(out) + met, statuses, err := a.requirementAndPermissionStatus(out) + if err != nil { + // TODO: account for Bad Rule as well + logger.Info("invalid install strategy") + out.SetPhaseWithEvent(v1alpha1.CSVPhaseFailed, v1alpha1.CSVReasonInvalidStrategy, fmt.Sprintf("install strategy invalid: %s", err.Error()), now, a.recorder) + return + } out.SetRequirementStatus(statuses) if !met { logger.Info("requirements were not met") - out.SetPhase(v1alpha1.CSVPhasePending, v1alpha1.CSVReasonRequirementsNotMet, "one or more requirements couldn't be found") + out.SetPhaseWithEvent(v1alpha1.CSVPhasePending, v1alpha1.CSVReasonRequirementsNotMet, "one or more requirements couldn't be found", now, a.recorder) syncError = ErrRequirementsNotMet return } - // check for CRD ownership conflicts - if syncError = a.crdOwnerConflicts(out, a.csvsInNamespace(out.GetNamespace())); syncError != nil { - out.SetPhase(v1alpha1.CSVPhaseFailed, v1alpha1.CSVReasonOwnerConflict, fmt.Sprintf("owner conflict: %s", syncError)) + // Check for CRD ownership conflicts + if syncError = a.crdOwnerConflicts(out, a.csvSet(out.GetNamespace(), v1alpha1.CSVPhaseAny)); syncError != nil { + if syncError == ErrCRDOwnerConflict { + out.SetPhaseWithEventIfChanged(v1alpha1.CSVPhaseFailed, v1alpha1.CSVReasonOwnerConflict, syncError.Error(), now, a.recorder) + } + return + } + + // Check for APIServices ownership conflicts + if syncError = a.apiServiceOwnerConflicts(out); syncError != nil { + if syncError == ErrAPIServiceOwnerConflict { + out.SetPhaseWithEventIfChanged(v1alpha1.CSVPhaseFailed, v1alpha1.CSVReasonOwnerConflict, syncError.Error(), now, a.recorder) + } return } logger.Info("scheduling ClusterServiceVersion for install") - out.SetPhase(v1alpha1.CSVPhaseInstallReady, v1alpha1.CSVReasonRequirementsMet, "all requirements found, attempting install") + out.SetPhaseWithEvent(v1alpha1.CSVPhaseInstallReady, v1alpha1.CSVReasonRequirementsMet, "all requirements found, attempting install", now, a.recorder) case v1alpha1.CSVPhaseInstallReady: installer, strategy, _ := a.parseStrategiesAndUpdateStatus(out) if strategy == nil { - // parseStrategiesAndUpdateStatus sets CSV status + return + } + + // Install owned APIServices and update strategy with serving cert data + strategy, syncError = a.installOwnedAPIServiceRequirements(out, strategy) + if syncError != nil { + out.SetPhaseWithEvent(v1alpha1.CSVPhaseFailed, v1alpha1.CSVReasonComponentFailed, fmt.Sprintf("install API services failed: %s", syncError), now, a.recorder) return } if syncError = installer.Install(strategy); syncError != nil { - out.SetPhase(v1alpha1.CSVPhaseFailed, v1alpha1.CSVReasonComponentFailed, fmt.Sprintf("install strategy failed: %s", syncError)) + out.SetPhaseWithEvent(v1alpha1.CSVPhaseFailed, v1alpha1.CSVReasonComponentFailed, fmt.Sprintf("install strategy failed: %s", syncError), now, a.recorder) return } - out.SetPhase(v1alpha1.CSVPhaseInstalling, v1alpha1.CSVReasonInstallSuccessful, "waiting for install components to report healthy") - a.requeueCSV(out.GetName(), out.GetNamespace()) + out.SetPhaseWithEvent(v1alpha1.CSVPhaseInstalling, v1alpha1.CSVReasonInstallSuccessful, "waiting for install components to report healthy", now, a.recorder) + err := a.csvQueueSet.Requeue(out.GetName(), out.GetNamespace()) + if err != nil { + a.Log.Warn(err.Error()) + } return + case v1alpha1.CSVPhaseInstalling: installer, strategy, _ := a.parseStrategiesAndUpdateStatus(out) if strategy == nil { - // parseStrategiesAndUpdateStatus sets CSV status return } - if installErr := a.updateInstallStatus(out, installer, strategy, v1alpha1.CSVReasonWaiting); installErr == nil { + if installErr := a.updateInstallStatus(out, installer, strategy, v1alpha1.CSVPhaseInstalling, v1alpha1.CSVReasonWaiting); installErr == nil { logger.WithField("strategy", out.Spec.InstallStrategy.StrategyName).Infof("install strategy successful") + } else { + // Set phase to failed if it's been a long time since the last transition (5 minutes) + if metav1.Now().Sub(out.Status.LastTransitionTime.Time) >= 5*time.Minute { + out.SetPhaseWithEventIfChanged(v1alpha1.CSVPhaseFailed, v1alpha1.CSVReasonInstallCheckFailed, fmt.Sprintf("install timeout"), now, a.recorder) + } } case v1alpha1.CSVPhaseSucceeded: installer, strategy, _ := a.parseStrategiesAndUpdateStatus(out) if strategy == nil { - // parseStrategiesAndUpdateStatus sets CSV status return } - if installErr := a.updateInstallStatus(out, installer, strategy, v1alpha1.CSVReasonComponentUnhealthy); installErr != nil { - logger.WithField("strategy", out.Spec.InstallStrategy.StrategyName).Infof("unhealthy component: %s", installErr) + + // Check if any generated resources are missing + if err := a.checkAPIServiceResources(out, certs.PEMSHA256); err != nil { + out.SetPhaseWithEvent(v1alpha1.CSVPhaseFailed, v1alpha1.CSVReasonAPIServiceResourceIssue, err.Error(), now, a.recorder) + return + } + + // Check if it's time to refresh owned APIService certs + if a.shouldRotateCerts(out) { + out.SetPhaseWithEvent(v1alpha1.CSVPhasePending, v1alpha1.CSVReasonNeedsCertRotation, "owned APIServices need cert refresh", now, a.recorder) + return + } + + // Ensure requirements are still present + met, statuses, err := a.requirementAndPermissionStatus(out) + if err != nil { + logger.Info("invalid install strategy") + out.SetPhaseWithEvent(v1alpha1.CSVPhaseFailed, v1alpha1.CSVReasonInvalidStrategy, fmt.Sprintf("install strategy invalid: %s", err.Error()), now, a.recorder) + return + } else if !met { + out.SetRequirementStatus(statuses) + out.SetPhaseWithEvent(v1alpha1.CSVPhaseFailed, v1alpha1.CSVReasonRequirementsNotMet, fmt.Sprintf("requirements no longer met"), now, a.recorder) + return + } + + // Check install status + if installErr := a.updateInstallStatus(out, installer, strategy, v1alpha1.CSVPhaseFailed, v1alpha1.CSVReasonComponentUnhealthy); installErr != nil { + logger.WithField("strategy", out.Spec.InstallStrategy.StrategyName).Warnf("unhealthy component: %s", installErr) + return + } + + case v1alpha1.CSVPhaseFailed: + installer, strategy, _ := a.parseStrategiesAndUpdateStatus(out) + if strategy == nil { + return + } + + // Check if failed due to unsupported InstallModes + if out.Status.Reason == v1alpha1.CSVReasonNoTargetNamespaces || + out.Status.Reason == v1alpha1.CSVReasonNoOperatorGroup || + out.Status.Reason == v1alpha1.CSVReasonTooManyOperatorGroups || + out.Status.Reason == v1alpha1.CSVReasonUnsupportedOperatorGroup { + logger.Info("InstallModes now support target namespaces. Transitioning to Pending...") + // Check occurred before switch, safe to transition to pending + out.SetPhaseWithEvent(v1alpha1.CSVPhasePending, v1alpha1.CSVReasonRequirementsUnknown, "InstallModes now support target namespaces", now, a.recorder) + return + } + + // Check if failed due to conflicting OperatorGroups + if out.Status.Reason == v1alpha1.CSVReasonInterOperatorGroupOwnerConflict { + logger.Info("OperatorGroup no longer intersecting with conflicting owner. Transitioning to Pending...") + // Check occurred before switch, safe to transition to pending + out.SetPhaseWithEvent(v1alpha1.CSVPhasePending, v1alpha1.CSVReasonRequirementsUnknown, "OperatorGroup no longer intersecting with conflicting owner", now, a.recorder) + return + } + + // Check if failed due to an attempt to modify a static OperatorGroup + if out.Status.Reason == v1alpha1.CSVReasonCannotModifyStaticOperatorGroupProvidedAPIs { + logger.Info("static OperatorGroup and intersecting groups now support providedAPIs...") + // Check occurred before switch, safe to transition to pending + out.SetPhaseWithEvent(v1alpha1.CSVPhasePending, v1alpha1.CSVReasonRequirementsUnknown, "static OperatorGroup and intersecting groups now support providedAPIs", now, a.recorder) + return + } + + // Check if requirements exist + met, statuses, err := a.requirementAndPermissionStatus(out) + if err != nil && out.Status.Reason != v1alpha1.CSVReasonInvalidStrategy { + logger.Warn("invalid install strategy") + out.SetPhaseWithEvent(v1alpha1.CSVPhaseFailed, v1alpha1.CSVReasonInvalidStrategy, fmt.Sprintf("install strategy invalid: %s", err.Error()), now, a.recorder) + return + } else if !met { + out.SetRequirementStatus(statuses) + out.SetPhaseWithEvent(v1alpha1.CSVPhasePending, v1alpha1.CSVReasonRequirementsNotMet, fmt.Sprintf("requirements not met"), now, a.recorder) + return + } + + // Check if any generated resources are missing and that OLM can action on them + if err := a.checkAPIServiceResources(out, certs.PEMSHA256); err != nil { + if a.apiServiceResourceErrorActionable(err) { + // Check if API services are adoptable. If not, keep CSV as Failed state + out.SetPhaseWithEvent(v1alpha1.CSVPhasePending, v1alpha1.CSVReasonAPIServiceResourcesNeedReinstall, err.Error(), now, a.recorder) + } + return + } + + // Check if it's time to refresh owned APIService certs + if a.shouldRotateCerts(out) { + out.SetPhaseWithEvent(v1alpha1.CSVPhasePending, v1alpha1.CSVReasonNeedsCertRotation, "owned APIServices need cert refresh", now, a.recorder) + return + } + + // Check install status + if installErr := a.updateInstallStatus(out, installer, strategy, v1alpha1.CSVPhasePending, v1alpha1.CSVReasonNeedsReinstall); installErr != nil { + logger.WithField("strategy", out.Spec.InstallStrategy.StrategyName).Warnf("needs reinstall: %s", installErr) } + case v1alpha1.CSVPhaseReplacing: // determine CSVs that are safe to delete by finding a replacement chain to a CSV that's running // since we don't know what order we'll process replacements, we have to guard against breaking that chain @@ -272,17 +1064,24 @@ func (a *Operator) transitionCSVState(in v1alpha1.ClusterServiceVersion) (out *v return } - // if we can find a newer version that's successfully installed, we're safe to mark all intermediates + // If we can find a newer version that's successfully installed, we're safe to mark all intermediates for _, csv := range a.findIntermediatesForDeletion(out) { // we only mark them in this step, in case some get deleted but others fail and break the replacement chain - csv.SetPhase(v1alpha1.CSVPhaseDeleting, v1alpha1.CSVReasonReplaced, "has been replaced by a newer ClusterServiceVersion that has successfully installed.") - // ignore errors and success here; this step is just an optimization to speed up GC - a.client.OperatorsV1alpha1().ClusterServiceVersions(csv.GetNamespace()).UpdateStatus(csv) - a.requeueCSV(csv.GetName(), csv.GetNamespace()) + csv.SetPhaseWithEvent(v1alpha1.CSVPhaseDeleting, v1alpha1.CSVReasonReplaced, "has been replaced by a newer ClusterServiceVersion that has successfully installed.", now, a.recorder) + + // Ignore errors and success here; this step is just an optimization to speed up GC + _, _ = a.client.OperatorsV1alpha1().ClusterServiceVersions(csv.GetNamespace()).UpdateStatus(csv) + err := a.csvQueueSet.Requeue(csv.GetName(), csv.GetNamespace()) + if err != nil { + a.Log.Warn(err.Error()) + } } - // if there's no newer version, requeue for processing (likely will be GCable before resync) - a.requeueCSV(out.GetName(), out.GetNamespace()) + // If there's no newer version, requeue for processing (likely will be GCable before resync) + err := a.csvQueueSet.Requeue(out.GetName(), out.GetNamespace()) + if err != nil { + a.Log.Warn(err.Error()) + } case v1alpha1.CSVPhaseDeleting: var immediate int64 = 0 syncError = a.client.OperatorsV1alpha1().ClusterServiceVersions(out.GetNamespace()).Delete(out.GetName(), &metav1.DeleteOptions{GracePeriodSeconds: &immediate}) @@ -296,41 +1095,48 @@ func (a *Operator) transitionCSVState(in v1alpha1.ClusterServiceVersion) (out *v // findIntermediatesForDeletion starts at csv and follows the replacement chain until one is running and active func (a *Operator) findIntermediatesForDeletion(csv *v1alpha1.ClusterServiceVersion) (csvs []*v1alpha1.ClusterServiceVersion) { - csvsInNamespace := a.csvsInNamespace(csv.GetNamespace()) + csvsInNamespace := a.csvSet(csv.GetNamespace(), v1alpha1.CSVPhaseAny) current := csv // isBeingReplaced returns a copy next := a.isBeingReplaced(current, csvsInNamespace) for next != nil { csvs = append(csvs, current) - log.Debugf("checking to see if %s is running so we can delete %s", next.GetName(), csv.GetName()) + a.Log.Debugf("checking to see if %s is running so we can delete %s", next.GetName(), csv.GetName()) installer, nextStrategy, currentStrategy := a.parseStrategiesAndUpdateStatus(next) if nextStrategy == nil { - log.Debugf("couldn't get strategy for %s", next.GetName()) + a.Log.Debugf("couldn't get strategy for %s", next.GetName()) continue } if currentStrategy == nil { - log.Debugf("couldn't get strategy for %s", next.GetName()) + a.Log.Debugf("couldn't get strategy for %s", next.GetName()) continue } installed, _ := installer.CheckInstalled(nextStrategy) - if installed && !next.IsObsolete() { + if installed && !next.IsObsolete() && next.Status.Phase == v1alpha1.CSVPhaseSucceeded { return csvs } current = next next = a.isBeingReplaced(current, csvsInNamespace) } + return nil } -// csvsInNamespace finds all CSVs in a namespace -func (a *Operator) csvsInNamespace(namespace string) map[string]*v1alpha1.ClusterServiceVersion { - csvsInNamespace, err := a.client.OperatorsV1alpha1().ClusterServiceVersions(namespace).List(metav1.ListOptions{}) +// csvSet gathers all CSVs in the given namespace into a map keyed by CSV name; if metav1.NamespaceAll gets the set across all namespaces +func (a *Operator) csvSet(namespace string, phase v1alpha1.ClusterServiceVersionPhase) map[string]*v1alpha1.ClusterServiceVersion { + csvsInNamespace, err := a.lister.OperatorsV1alpha1().ClusterServiceVersionLister().ClusterServiceVersions(namespace).List(labels.Everything()) + if err != nil { + a.Log.Warnf("could not list CSVs while constructing CSV set") return nil } - csvs := make(map[string]*v1alpha1.ClusterServiceVersion, len(csvsInNamespace.Items)) - for _, csv := range csvsInNamespace.Items { + + csvs := make(map[string]*v1alpha1.ClusterServiceVersion, len(csvsInNamespace)) + for _, csv := range csvsInNamespace { + if phase != v1alpha1.CSVPhaseAny && csv.Status.Phase != phase { + continue + } csvs[csv.Name] = csv.DeepCopy() } return csvs @@ -341,35 +1147,54 @@ func (a *Operator) checkReplacementsAndUpdateStatus(csv *v1alpha1.ClusterService if csv.Status.Phase == v1alpha1.CSVPhaseReplacing || csv.Status.Phase == v1alpha1.CSVPhaseDeleting { return nil } - if replacement := a.isBeingReplaced(csv, a.csvsInNamespace(csv.GetNamespace())); replacement != nil { - log.Infof("newer ClusterServiceVersion replacing %s, no-op", csv.SelfLink) + if replacement := a.isBeingReplaced(csv, a.csvSet(csv.GetNamespace(), v1alpha1.CSVPhaseAny)); replacement != nil { + a.Log.Infof("newer ClusterServiceVersion replacing %s, no-op", csv.SelfLink) msg := fmt.Sprintf("being replaced by csv: %s", replacement.SelfLink) - csv.SetPhase(v1alpha1.CSVPhaseReplacing, v1alpha1.CSVReasonBeingReplaced, msg) + csv.SetPhaseWithEvent(v1alpha1.CSVPhaseReplacing, v1alpha1.CSVReasonBeingReplaced, msg, timeNow(), a.recorder) + metrics.CSVUpgradeCount.Inc() return fmt.Errorf("replacing") } return nil } -func (a *Operator) updateInstallStatus(csv *v1alpha1.ClusterServiceVersion, installer install.StrategyInstaller, strategy install.Strategy, requeueConditionReason v1alpha1.ConditionReason) error { - installed, strategyErr := installer.CheckInstalled(strategy) - if installed { +func (a *Operator) updateInstallStatus(csv *v1alpha1.ClusterServiceVersion, installer install.StrategyInstaller, strategy install.Strategy, requeuePhase v1alpha1.ClusterServiceVersionPhase, requeueConditionReason v1alpha1.ConditionReason) error { + apiServicesInstalled, apiServiceErr := a.areAPIServicesAvailable(csv) + strategyInstalled, strategyErr := installer.CheckInstalled(strategy) + now := timeNow() + + if strategyInstalled && apiServicesInstalled { // if there's no error, we're successfully running - if csv.Status.Phase != v1alpha1.CSVPhaseSucceeded { - csv.SetPhase(v1alpha1.CSVPhaseSucceeded, v1alpha1.CSVReasonInstallSuccessful, "install strategy completed with no errors") - } + csv.SetPhaseWithEventIfChanged(v1alpha1.CSVPhaseSucceeded, v1alpha1.CSVReasonInstallSuccessful, "install strategy completed with no errors", now, a.recorder) return nil } // installcheck determined we can't progress (e.g. deployment failed to come up in time) if install.IsErrorUnrecoverable(strategyErr) { - csv.SetPhase(v1alpha1.CSVPhaseFailed, v1alpha1.CSVReasonInstallCheckFailed, fmt.Sprintf("install failed: %s", strategyErr)) + csv.SetPhaseWithEventIfChanged(v1alpha1.CSVPhaseFailed, v1alpha1.CSVReasonInstallCheckFailed, fmt.Sprintf("install failed: %s", strategyErr), now, a.recorder) return strategyErr } - // if there's an error checking install that shouldn't fail the strategy, requeue with message + if apiServiceErr != nil { + csv.SetPhaseWithEventIfChanged(v1alpha1.CSVPhaseFailed, v1alpha1.CSVReasonAPIServiceInstallFailed, fmt.Sprintf("APIService install failed: %s", apiServiceErr), now, a.recorder) + return apiServiceErr + } + + if !apiServicesInstalled { + csv.SetPhaseWithEventIfChanged(requeuePhase, requeueConditionReason, fmt.Sprintf("APIServices not installed"), now, a.recorder) + if err := a.csvQueueSet.Requeue(csv.GetName(), csv.GetNamespace()); err != nil { + a.Log.Warn(err.Error()) + } + + return fmt.Errorf("APIServices not installed") + } + if strategyErr != nil { - csv.SetPhase(v1alpha1.CSVPhaseInstalling, requeueConditionReason, fmt.Sprintf("installing: %s", strategyErr)) + csv.SetPhaseWithEventIfChanged(requeuePhase, requeueConditionReason, fmt.Sprintf("installing: %s", strategyErr), now, a.recorder) + if err := a.csvQueueSet.Requeue(csv.GetName(), csv.GetNamespace()); err != nil { + a.Log.Warn(err.Error()) + } + return strategyErr } @@ -380,14 +1205,18 @@ func (a *Operator) updateInstallStatus(csv *v1alpha1.ClusterServiceVersion, inst func (a *Operator) parseStrategiesAndUpdateStatus(csv *v1alpha1.ClusterServiceVersion) (install.StrategyInstaller, install.Strategy, install.Strategy) { strategy, err := a.resolver.UnmarshalStrategy(csv.Spec.InstallStrategy) if err != nil { - csv.SetPhase(v1alpha1.CSVPhaseFailed, v1alpha1.CSVReasonInvalidStrategy, fmt.Sprintf("install strategy invalid: %s", err)) + csv.SetPhaseWithEvent(v1alpha1.CSVPhaseFailed, v1alpha1.CSVReasonInvalidStrategy, fmt.Sprintf("install strategy invalid: %s", err), timeNow(), a.recorder) return nil, nil, nil } previousCSV := a.isReplacing(csv) var previousStrategy install.Strategy if previousCSV != nil { - a.requeueCSV(previousCSV.Name, previousCSV.Namespace) + err = a.csvQueueSet.Requeue(previousCSV.Name, previousCSV.Namespace) + if err != nil { + a.Log.Warn(err.Error()) + } + previousStrategy, err = a.resolver.UnmarshalStrategy(previousCSV.Spec.InstallStrategy) if err != nil { previousStrategy = nil @@ -395,74 +1224,58 @@ func (a *Operator) parseStrategiesAndUpdateStatus(csv *v1alpha1.ClusterServiceVe } strName := strategy.GetStrategyName() - installer := a.resolver.InstallerForStrategy(strName, a.OpClient, csv, previousStrategy) + installer := a.resolver.InstallerForStrategy(strName, a.OpClient, a.lister, csv, csv.Annotations, previousStrategy) return installer, strategy, previousStrategy } -func (a *Operator) requirementStatus(csv *v1alpha1.ClusterServiceVersion) (met bool, statuses []v1alpha1.RequirementStatus) { - met = true - for _, r := range csv.GetAllCRDDescriptions() { - status := v1alpha1.RequirementStatus{ - Group: "apiextensions.k8s.io", - Version: "v1beta1", - Kind: "CustomResourceDefinition", - Name: r.Name, - } - crd, err := a.OpClient.ApiextensionsV1beta1Interface().ApiextensionsV1beta1().CustomResourceDefinitions().Get(r.Name, metav1.GetOptions{}) - if err != nil { - status.Status = "NotPresent" - met = false - } else { - status.Status = "Present" - status.UUID = string(crd.GetUID()) - } - statuses = append(statuses, status) - } - return -} - -func (a *Operator) crdOwnerConflicts(in *v1alpha1.ClusterServiceVersion, csvsInNamespace map[string]*v1alpha1.ClusterServiceVersion) error { - owned := false +func (a *Operator) crdOwnerConflicts(in *v1alpha1.ClusterServiceVersion, csvs map[string]*v1alpha1.ClusterServiceVersion) error { for _, crd := range in.Spec.CustomResourceDefinitions.Owned { - for csvName, csv := range csvsInNamespace { - if csvName == in.GetName() { - continue - } - if csv.OwnsCRD(crd.Name) { - owned = true - } - if owned && in.Spec.Replaces == csvName { - return nil + for name, csv := range csvs { + if name != in.GetName() && in.Spec.Replaces != name && csv.OwnsCRD(crd.Name) { + return ErrCRDOwnerConflict } } } - if owned { - return ErrCRDOwnerConflict - } + return nil } -// annotateNamespace is the method that gets called when we see a namespace event in the cluster -func (a *Operator) annotateNamespace(obj interface{}) (syncError error) { - namespace, ok := obj.(*corev1.Namespace) - if !ok { - log.Debugf("wrong type: %#v", obj) - return fmt.Errorf("casting Namespace failed") +func (a *Operator) apiServiceOwnerConflicts(csv *v1alpha1.ClusterServiceVersion) error { + // Get replacing CSV if exists + replacing, err := a.lister.OperatorsV1alpha1().ClusterServiceVersionLister().ClusterServiceVersions(csv.GetNamespace()).Get(csv.Spec.Replaces) + if err != nil && !k8serrors.IsNotFound(err) && !k8serrors.IsGone(err) { + return err } - log.Infof("syncing Namespace: %s", namespace.GetName()) - if err := a.annotator.AnnotateNamespace(namespace); err != nil { - log.Infof("error annotating namespace '%s'", namespace.GetName()) - return err + owners := []ownerutil.Owner{csv} + if replacing != nil { + owners = append(owners, replacing) + } + + for _, desc := range csv.GetOwnedAPIServiceDescriptions() { + // Check if the APIService exists + apiService, err := a.lister.APIRegistrationV1().APIServiceLister().Get(desc.GetName()) + if err != nil && !k8serrors.IsNotFound(err) && !k8serrors.IsGone(err) { + return err + } + + if apiService == nil { + continue + } + + if !ownerutil.AdoptableLabels(apiService.GetLabels(), true, owners...) { + return ErrAPIServiceOwnerConflict + } } + return nil } func (a *Operator) isBeingReplaced(in *v1alpha1.ClusterServiceVersion, csvsInNamespace map[string]*v1alpha1.ClusterServiceVersion) (replacedBy *v1alpha1.ClusterServiceVersion) { for _, csv := range csvsInNamespace { - log.Infof("checking %s", csv.GetName()) + a.Log.Infof("checking %s", csv.GetName()) if csv.Spec.Replaces == in.GetName() { - log.Infof("%s replaced by %s", in.GetName(), csv.GetName()) + a.Log.Infof("%s replaced by %s", in.GetName(), csv.GetName()) replacedBy = csv.DeepCopy() return } @@ -471,14 +1284,182 @@ func (a *Operator) isBeingReplaced(in *v1alpha1.ClusterServiceVersion, csvsInNam } func (a *Operator) isReplacing(in *v1alpha1.ClusterServiceVersion) *v1alpha1.ClusterServiceVersion { - log.Debugf("checking if csv is replacing an older version") + a.Log.Debugf("checking if csv is replacing an older version") if in.Spec.Replaces == "" { return nil } - previous, err := a.client.OperatorsV1alpha1().ClusterServiceVersions(in.GetNamespace()).Get(in.Spec.Replaces, metav1.GetOptions{}) + previous, err := a.lister.OperatorsV1alpha1().ClusterServiceVersionLister().ClusterServiceVersions(in.GetNamespace()).Get(in.Spec.Replaces) if err != nil { - log.Debugf("unable to get previous csv: %s", err.Error()) + a.Log.WithField("replacing", in.Spec.Replaces).WithError(err).Debugf("unable to get previous csv") return nil } return previous } + +func (a *Operator) handleDeletion(obj interface{}) { + metaObj, ok := obj.(metav1.Object) + if !ok { + tombstone, ok := obj.(cache.DeletedFinalStateUnknown) + if !ok { + utilruntime.HandleError(fmt.Errorf("Couldn't get object from tombstone %#v", obj)) + return + } + + metaObj, ok = tombstone.Obj.(metav1.Object) + if !ok { + utilruntime.HandleError(fmt.Errorf("Tombstone contained object that is not a metav1.Object %#v", obj)) + return + } + } + logger := a.Log.WithFields(logrus.Fields{ + "name": metaObj.GetName(), + "namespace": metaObj.GetNamespace(), + "self": metaObj.GetSelfLink(), + }) + logger.Debug("handling resource deletion") + + logger.Debug("requeueing owner csvs") + a.requeueOwnerCSVs(metaObj) + + // Requeue CSVs with provided and required labels (for CRDs) + if labelSets, err := a.apiLabeler.LabelSetsFor(metaObj); err != nil { + logger.WithError(err).Warn("couldn't create label set") + } else if len(labelSets) > 0 { + logger.Debug("requeueing providing/requiring csvs") + a.requeueCSVsByLabelSet(logger, labelSets...) + } +} + +func (a *Operator) requeueCSVsByLabelSet(logger *logrus.Entry, labelSets ...labels.Set) { + keys, err := index.LabelIndexKeys(a.csvIndexers, labelSets...) + if err != nil { + logger.WithError(err).Debug("issue getting csvs by label index") + return + } + + for _, key := range keys { + if err := a.csvQueueSet.RequeueByKey(key); err != nil { + logger.WithError(err).Debug("cannot requeue requiring/providing csv") + } else { + logger.WithField("key", key).Debug("csv successfully requeued on crd change") + } + } +} + +func (a *Operator) requeueOwnerCSVs(ownee metav1.Object) { + logger := a.Log.WithFields(logrus.Fields{ + "ownee": ownee.GetName(), + "selflink": ownee.GetSelfLink(), + "namespace": ownee.GetNamespace(), + }) + + // Attempt to requeue CSV owners in the same namespace as the object + owners := ownerutil.GetOwnersByKind(ownee, v1alpha1.ClusterServiceVersionKind) + if len(owners) > 0 && ownee.GetNamespace() != metav1.NamespaceAll { + for _, ownerCSV := range owners { + // Since cross-namespace CSVs can't exist we're guaranteed the owner will be in the same namespace + err := a.csvQueueSet.Requeue(ownerCSV.Name, ownee.GetNamespace()) + if err != nil { + logger.Warn(err.Error()) + } + } + return + } + + // Requeue owners based on labels + if name, ns, ok := ownerutil.GetOwnerByKindLabel(ownee, v1alpha1.ClusterServiceVersionKind); ok { + err := a.csvQueueSet.Requeue(name, ns) + if err != nil { + logger.Warn(err.Error()) + } + } +} + +func (a *Operator) cleanupCSVDeployments(logger *logrus.Entry, csv *v1alpha1.ClusterServiceVersion) { + // Extract the InstallStrategy for the deployment + strategy, err := a.resolver.UnmarshalStrategy(csv.Spec.InstallStrategy) + if err != nil { + logger.Warn("could not parse install strategy while cleaning up CSV deployment") + return + } + + // Assume the strategy is for a deployment + strategyDetailsDeployment, ok := strategy.(*install.StrategyDetailsDeployment) + if !ok { + logger.Warnf("could not cast install strategy as type %T", strategyDetailsDeployment) + return + } + + // Delete deployments + for _, spec := range strategyDetailsDeployment.DeploymentSpecs { + logger := logger.WithField("deployment", spec.Name) + logger.Debug("cleaning up CSV deployment") + if err := a.OpClient.DeleteDeployment(csv.GetNamespace(), spec.Name, &metav1.DeleteOptions{}); err != nil { + logger.WithField("err", err).Warn("error cleaning up CSV deployment") + } + } +} + +func (a *Operator) ensureDeploymentAnnotations(logger *logrus.Entry, csv *v1alpha1.ClusterServiceVersion) error { + if !csv.IsSafeToUpdateOperatorGroupAnnotations() { + return nil + } + + // Get csv operatorgroup annotations + annotations := a.copyOperatorGroupAnnotations(&csv.ObjectMeta) + + // Extract the InstallStrategy for the deployment + strategy, err := a.resolver.UnmarshalStrategy(csv.Spec.InstallStrategy) + if err != nil { + logger.Warn("could not parse install strategy while cleaning up CSV deployment") + return nil + } + + // Assume the strategy is for a deployment + strategyDetailsDeployment, ok := strategy.(*install.StrategyDetailsDeployment) + if !ok { + logger.Warnf("could not cast install strategy as type %T", strategyDetailsDeployment) + return nil + } + + existingDeployments, err := a.lister.AppsV1().DeploymentLister().Deployments(csv.GetNamespace()).List(ownerutil.CSVOwnerSelector(csv)) + if err != nil { + return err + } + + // compare deployments to see if any need to be created/updated + updateErrs := []error{} + for _, dep := range existingDeployments { + if dep.Spec.Template.Annotations == nil { + dep.Spec.Template.Annotations = map[string]string{} + } + for key, value := range annotations { + dep.Spec.Template.Annotations[key] = value + } + if _, _, err := a.OpClient.UpdateDeployment(dep); err != nil { + updateErrs = append(updateErrs, err) + } + } + logger.Info("updated annotations to match current operatorgroup") + + return utilerrors.NewAggregate(updateErrs) +} + +// ensureLabels merges a label set with a CSV's labels and attempts to update the CSV if the merged set differs from the CSV's original labels. +func (a *Operator) ensureLabels(in *v1alpha1.ClusterServiceVersion, labelSets ...labels.Set) (*v1alpha1.ClusterServiceVersion, error) { + csvLabelSet := labels.Set(in.GetLabels()) + merged := csvLabelSet + for _, labelSet := range labelSets { + merged = labels.Merge(merged, labelSet) + } + if labels.Equals(csvLabelSet, merged) { + return in, nil + } + + a.Log.WithField("labels", merged).Error("Labels updated!") + + out := in.DeepCopy() + out.SetLabels(merged) + out, err := a.client.OperatorsV1alpha1().ClusterServiceVersions(out.GetNamespace()).Update(out) + return out, err +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/olm/operatorgroup.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/olm/operatorgroup.go new file mode 100644 index 0000000000..16449f9aad --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/olm/operatorgroup.go @@ -0,0 +1,781 @@ +package olm + +import ( + "fmt" + "reflect" + "strings" + + v1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + rbacv1 "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/util/errors" + utillabels "k8s.io/kubernetes/pkg/util/labels" + + "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install" + "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver" + "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil" +) + +const ( + operatorGroupAggregrationKeyPrefix = "olm.opgroup.permissions/aggregate-to-" + kubeRBACAggregationKeyPrefix = "rbac.authorization.k8s.io/aggregate-to-" + AdminSuffix = "admin" + EditSuffix = "edit" + ViewSuffix = "view" +) + +var ( + AdminVerbs = []string{"*"} + EditVerbs = []string{"create", "update", "patch", "delete"} + ViewVerbs = []string{"get", "list", "watch"} + Suffices = []string{AdminSuffix, EditSuffix, ViewSuffix} + VerbsForSuffix = map[string][]string{ + AdminSuffix: AdminVerbs, + EditSuffix: EditVerbs, + ViewSuffix: ViewVerbs, + } +) + +func (a *Operator) syncOperatorGroups(obj interface{}) error { + op, ok := obj.(*v1.OperatorGroup) + if !ok { + a.Log.Debugf("wrong type: %#v\n", obj) + return fmt.Errorf("casting OperatorGroup failed") + } + + logger := a.Log.WithFields(logrus.Fields{ + "operatorGroup": op.GetName(), + "namespace": op.GetNamespace(), + }) + + targetNamespaces, err := a.updateNamespaceList(op) + if err != nil { + logger.WithError(err).Warn("issue getting operatorgroup target namespaces") + return err + } + logger.WithField("targetNamespaces", targetNamespaces).Debug("updated target namespaces") + + if namespacesChanged(targetNamespaces, op.Status.Namespaces) { + // Update operatorgroup target namespace selection + logger.WithField("targets", targetNamespaces).Debug("namespace change detected") + op.Status = v1.OperatorGroupStatus{ + Namespaces: targetNamespaces, + LastUpdated: timeNow(), + } + + if _, err = a.client.OperatorsV1().OperatorGroups(op.GetNamespace()).UpdateStatus(op); err != nil && !k8serrors.IsNotFound(err) { + logger.WithError(err).Warn("operatorgroup update failed") + return err + } + logger.Debug("namespace change detected and operatorgroup status updated") + // CSV requeue is handled by the succeeding sync in `annotateCSVs` + return nil + } + + logger.Debug("check that operatorgroup has updated CSV anotations") + err = a.annotateCSVs(op, targetNamespaces, logger) + if err != nil { + logger.WithError(err).Warn("failed to annotate CSVs in operatorgroup after group change") + return err + } + logger.Debug("OperatorGroup CSV annotation completed") + + if err := a.ensureOpGroupClusterRoles(op); err != nil { + logger.WithError(err).Warn("failed to ensure operatorgroup clusterroles") + return err + } + logger.Debug("operatorgroup clusterroles ensured") + + // Requeue all CSVs that provide the same APIs (including those removed). This notifies conflicting CSVs in + // intersecting groups that their conflict has possibly been resolved, either through resizing or through + // deletion of the conflicting CSV. + groupSurface := resolver.NewOperatorGroup(op) + groupProvidedAPIs := groupSurface.ProvidedAPIs() + providedAPIsForCSVs := a.providedAPIsFromCSVs(op, logger) + providedAPIsForGroup := providedAPIsForCSVs.Union(groupProvidedAPIs) + + csvs, err := a.findCSVsThatProvideAnyOf(providedAPIsForGroup) + if err != nil { + logger.WithError(err).Warn("could not find csvs that provide group apis") + } + for _, csv := range csvs { + logger.WithFields(logrus.Fields{ + "csv": csv.GetName(), + "namespace": csv.GetNamespace(), + }).Debug("requeueing provider") + if err := a.csvQueueSet.Requeue(csv.GetName(), csv.GetNamespace()); err != nil { + logger.WithError(err).Warn("could not requeue provider") + } + } + + a.pruneProvidedAPIs(op, groupProvidedAPIs, providedAPIsForCSVs, logger) + return nil +} + +func (a *Operator) annotateCSVs(group *v1.OperatorGroup, targetNamespaces []string, logger *logrus.Entry) error { + updateErrs := []error{} + targetNamespaceSet := resolver.NewNamespaceSet(targetNamespaces) + + for _, csv := range a.csvSet(group.GetNamespace(), v1alpha1.CSVPhaseAny) { + logger := logger.WithField("csv", csv.GetName()) + + originalNamespacesAnnotation, _ := a.copyOperatorGroupAnnotations(&csv.ObjectMeta)[v1.OperatorGroupTargetsAnnotationKey] + originalNamespaceSet := resolver.NewNamespaceSetFromString(originalNamespacesAnnotation) + + if a.operatorGroupAnnotationsDiffer(&csv.ObjectMeta, group) { + a.setOperatorGroupAnnotations(&csv.ObjectMeta, group, true) + // CRDs don't support strategic merge patching, but in the future if they do this should be updated to patch + if _, err := a.client.OperatorsV1alpha1().ClusterServiceVersions(csv.GetNamespace()).Update(csv); err != nil && !k8serrors.IsNotFound(err) { + logger.WithError(err).Warnf("error adding operatorgroup annotations") + updateErrs = append(updateErrs, err) + continue + } + } + + // requeue csvs in original namespaces or in new target namespaces (to capture removed/added namespaces) + requeueNamespaces := originalNamespaceSet.Union(targetNamespaceSet) + if !requeueNamespaces.IsAllNamespaces() { + for ns := range requeueNamespaces { + if err := a.csvQueueSet.Requeue(csv.GetName(), ns); err != nil { + logger.WithError(err).Warn("could not requeue csv") + } + } + } + // have to requeue in all namespaces, previous or new targets were AllNamespaces + if namespaces, err := a.lister.CoreV1().NamespaceLister().List(labels.Everything()); err != nil { + for _, ns := range namespaces { + if err := a.csvQueueSet.Requeue(csv.GetName(), ns.GetName()); err != nil { + logger.WithError(err).Warn("could not requeue csv") + } + } + } + } + return errors.NewAggregate(updateErrs) +} + +func (a *Operator) providedAPIsFromCSVs(group *v1.OperatorGroup, logger *logrus.Entry) resolver.APISet { + set := a.csvSet(group.Namespace, v1alpha1.CSVPhaseAny) + providedAPIsFromCSVs := make(resolver.APISet) + for _, csv := range set { + // Don't union providedAPIsFromCSVs if the CSV is copied (member of another OperatorGroup) + if csv.IsCopied() { + logger.Debug("csv is copied. not updating annotations or including in operatorgroup's provided api set") + continue + } + + // TODO: Throw out CSVs that aren't members of the group due to group related failures? + + // Union the providedAPIsFromCSVs from existing members of the group + operatorSurface, err := resolver.NewOperatorFromCSV(csv) + if err != nil { + logger.WithError(err).Warn("could not create OperatorSurface from csv") + continue + } + providedAPIsFromCSVs = providedAPIsFromCSVs.Union(operatorSurface.ProvidedAPIs().StripPlural()) + } + return providedAPIsFromCSVs +} + +func (a *Operator) pruneProvidedAPIs(group *v1.OperatorGroup, groupProvidedAPIs, providedAPIsFromCSVs resolver.APISet, logger *logrus.Entry) { + // Don't prune providedAPIsFromCSVs if static + if group.Spec.StaticProvidedAPIs { + a.Log.Debug("group has static provided apis. skipping provided api pruning") + return + } + + // Prune providedAPIs annotation if the cluster has fewer providedAPIs (handles CSV deletion) + if intersection := groupProvidedAPIs.Intersection(providedAPIsFromCSVs); len(intersection) < len(groupProvidedAPIs) { + difference := groupProvidedAPIs.Difference(intersection) + logger := logger.WithFields(logrus.Fields{ + "providedAPIsOnCluster": providedAPIsFromCSVs, + "providedAPIsAnnotation": groupProvidedAPIs, + "providedAPIDifference": difference, + "intersection": intersection, + }) + + // Don't need to check for nil annotations since we already know |annotations| > 0 + annotations := group.GetAnnotations() + annotations[v1.OperatorGroupProvidedAPIsAnnotationKey] = intersection.String() + group.SetAnnotations(annotations) + logger.Debug("removing provided apis from annotation to match cluster state") + if _, err := a.client.OperatorsV1().OperatorGroups(group.GetNamespace()).Update(group); err != nil && !k8serrors.IsNotFound(err) { + logger.WithError(err).Warn("could not update provided api annotations") + } + } + return +} + +// ensureProvidedAPIClusterRole ensures that a clusterrole exists (admin, edit, or view) for a single provided API Type +func (a *Operator) ensureProvidedAPIClusterRole(operatorGroup *v1.OperatorGroup, csv *v1alpha1.ClusterServiceVersion, namePrefix, suffix string, verbs []string, group, resource string, resourceNames []string) error { + clusterRole := &rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: namePrefix + suffix, + Labels: map[string]string{ + kubeRBACAggregationKeyPrefix + suffix: "true", + operatorGroupAggregrationKeyPrefix + suffix: operatorGroup.GetName(), + }, + }, + Rules: []rbacv1.PolicyRule{{Verbs: verbs, APIGroups: []string{group}, Resources: []string{resource}, ResourceNames: resourceNames}}, + } + existingCR, err := a.OpClient.KubernetesInterface().RbacV1().ClusterRoles().Create(clusterRole) + if k8serrors.IsAlreadyExists(err) { + if existingCR != nil && reflect.DeepEqual(existingCR.Labels, clusterRole.Labels) && reflect.DeepEqual(existingCR.Rules, clusterRole.Rules) { + return nil + } + if _, err = a.OpClient.UpdateClusterRole(clusterRole); err != nil { + a.Log.WithError(err).Errorf("Update existing cluster role failed: %v", clusterRole) + return err + } + } else if err != nil { + a.Log.WithError(err).Errorf("Create cluster role failed: %v", clusterRole) + return err + } + return nil +} + +// ensureClusterRolesForCSV ensures that ClusterRoles for writing and reading provided APIs exist for each operator +func (a *Operator) ensureClusterRolesForCSV(csv *v1alpha1.ClusterServiceVersion, operatorGroup *v1.OperatorGroup) error { + for _, owned := range csv.Spec.CustomResourceDefinitions.Owned { + nameGroupPair := strings.SplitN(owned.Name, ".", 2) // -> etcdclusters etcd.database.coreos.com + if len(nameGroupPair) != 2 { + return fmt.Errorf("invalid parsing of name '%v', got %v", owned.Name, nameGroupPair) + } + plural := nameGroupPair[0] + group := nameGroupPair[1] + namePrefix := fmt.Sprintf("%s-%s-", owned.Name, owned.Version) + + for suffix, verbs := range VerbsForSuffix { + if err := a.ensureProvidedAPIClusterRole(operatorGroup, csv, namePrefix, suffix, verbs, group, plural, nil); err != nil { + return err + } + } + if err := a.ensureProvidedAPIClusterRole(operatorGroup, csv, namePrefix+"crd", ViewSuffix, []string{"get"}, "apiextensions.k8s.io", "customresourcedefinitions", []string{owned.Name}); err != nil { + return err + } + } + for _, owned := range csv.Spec.APIServiceDefinitions.Owned { + namePrefix := fmt.Sprintf("%s-%s-", owned.Name, owned.Version) + for suffix, verbs := range VerbsForSuffix { + if err := a.ensureProvidedAPIClusterRole(operatorGroup, csv, namePrefix, suffix, verbs, owned.Group, owned.Name, nil); err != nil { + return err + } + } + } + return nil +} + +func (a *Operator) ensureRBACInTargetNamespace(csv *v1alpha1.ClusterServiceVersion, operatorGroup *v1.OperatorGroup) error { + targetNamespaces := operatorGroup.Status.Namespaces + if targetNamespaces == nil { + return nil + } + + strategyResolver := install.StrategyResolver{} + strategy, err := strategyResolver.UnmarshalStrategy(csv.Spec.InstallStrategy) + if err != nil { + return err + } + strategyDetailsDeployment, ok := strategy.(*install.StrategyDetailsDeployment) + if !ok { + return fmt.Errorf("could not cast install strategy as type %T", strategyDetailsDeployment) + } + ruleChecker := install.NewCSVRuleChecker(a.lister.RbacV1().RoleLister(), a.lister.RbacV1().RoleBindingLister(), a.lister.RbacV1().ClusterRoleLister(), a.lister.RbacV1().ClusterRoleBindingLister(), csv) + + logger := a.Log.WithField("opgroup", operatorGroup.GetName()).WithField("csv", csv.GetName()) + + // if OperatorGroup is global (all namespaces) we generate cluster roles / cluster role bindings instead + if len(targetNamespaces) == 1 && targetNamespaces[0] == corev1.NamespaceAll { + logger.Debug("opgroup is global") + + // synthesize cluster permissions to verify rbac + for _, p := range strategyDetailsDeployment.Permissions { + strategyDetailsDeployment.ClusterPermissions = append(strategyDetailsDeployment.ClusterPermissions, p) + } + strategyDetailsDeployment.Permissions = nil + permMet, _, err := a.permissionStatus(strategyDetailsDeployment, ruleChecker, corev1.NamespaceAll) + if err != nil { + return err + } + + // operator already has access at the cluster scope + if permMet { + logger.Debug("global operator has correct global permissions") + return nil + } + logger.Debug("lift roles/rolebindings to clusterroles/rolebindings") + if err := a.ensureSingletonRBAC(operatorGroup.GetNamespace(), csv); err != nil { + return err + } + + return nil + } + + // otherwise, create roles/rolebindings for each target namespace + for _, ns := range targetNamespaces { + if ns == operatorGroup.GetNamespace() { + continue + } + + permMet, _, err := a.permissionStatus(strategyDetailsDeployment, ruleChecker, ns) + if err != nil { + return err + } + // operator already has access in the target namespace + if permMet { + return nil + } + if err := a.ensureTenantRBAC(operatorGroup.GetNamespace(), ns, csv); err != nil { + return err + } + } + return nil +} + +func (a *Operator) ensureSingletonRBAC(operatorNamespace string, csv *v1alpha1.ClusterServiceVersion) error { + ownerSelector := ownerutil.CSVOwnerSelector(csv) + ownedRoles, err := a.lister.RbacV1().RoleLister().Roles(operatorNamespace).List(ownerSelector) + if err != nil { + return err + } + if len(ownedRoles) == 0 { + return fmt.Errorf("no owned roles found") + } + + for _, r := range ownedRoles { + a.Log.Debug("processing role") + _, err := a.lister.RbacV1().ClusterRoleLister().Get(r.GetName()) + if err != nil { + clusterRole := &rbacv1.ClusterRole{ + TypeMeta: metav1.TypeMeta{ + Kind: "ClusterRole", + APIVersion: r.APIVersion, + }, + ObjectMeta: metav1.ObjectMeta{ + Name: r.GetName(), + Labels: r.GetLabels(), + }, + Rules: append(r.Rules, rbacv1.PolicyRule{ + Verbs: ViewVerbs, + APIGroups: []string{corev1.GroupName}, + Resources: []string{"namespaces"}, + }), + } + if _, err := a.OpClient.CreateClusterRole(clusterRole); err != nil { + return err + } + a.Log.Debug("created cluster role") + } + } + + ownedRoleBindings, err := a.lister.RbacV1().RoleBindingLister().RoleBindings(operatorNamespace).List(ownerSelector) + if err != nil { + return err + } + if len(ownedRoleBindings) == 0 { + return fmt.Errorf("no owned rolebindings found") + } + + for _, r := range ownedRoleBindings { + _, err := a.lister.RbacV1().ClusterRoleBindingLister().Get(r.GetName()) + if err != nil { + clusterRoleBinding := &rbacv1.ClusterRoleBinding{ + TypeMeta: metav1.TypeMeta{ + Kind: "ClusterRoleBinding", + APIVersion: r.APIVersion, + }, + ObjectMeta: metav1.ObjectMeta{ + Name: r.GetName(), + Labels: r.GetLabels(), + }, + Subjects: r.Subjects, + RoleRef: rbacv1.RoleRef{ + APIGroup: r.RoleRef.APIGroup, + Kind: "ClusterRole", + Name: r.RoleRef.Name, + }, + } + if _, err := a.OpClient.CreateClusterRoleBinding(clusterRoleBinding); err != nil { + return err + } + } + } + return nil +} + +func (a *Operator) ensureTenantRBAC(operatorNamespace, targetNamespace string, csv *v1alpha1.ClusterServiceVersion) error { + targetCSV, err := a.lister.OperatorsV1alpha1().ClusterServiceVersionLister().ClusterServiceVersions(targetNamespace).Get(csv.GetName()) + if err != nil { + return err + } + ownerSelector := ownerutil.CSVOwnerSelector(csv) + ownedRoles, err := a.lister.RbacV1().RoleLister().Roles(operatorNamespace).List(ownerSelector) + if err != nil { + return err + } + + targetRoles, err := a.lister.RbacV1().RoleLister().Roles(targetNamespace).List(ownerutil.CSVOwnerSelector(targetCSV)) + if err != nil { + return err + } + + targetRolesByName := map[string]*rbacv1.Role{} + for _, r := range targetRoles { + targetRolesByName[r.GetName()] = r + } + + for _, ownedRole := range ownedRoles { + // don't trust the owner label + // TODO: this can skip objects that have owner labels but different ownerreferences + if !ownerutil.IsOwnedBy(ownedRole, csv) { + continue + } + + existing, ok := targetRolesByName[ownedRole.GetName()] + + // role already exists, update the rules + if ok { + existing.Rules = ownedRole.Rules + if _, err := a.OpClient.UpdateRole(existing); err != nil { + return err + } + continue + } + + // role doesn't exist, create it + // TODO: we can work around error cases here; if there's an un-owned role with a matching name we should generate instead + ownedRole.SetNamespace(targetNamespace) + ownedRole.SetOwnerReferences([]metav1.OwnerReference{ownerutil.NonBlockingOwner(targetCSV)}) + if err := ownerutil.AddOwnerLabels(ownedRole, targetCSV); err != nil { + return err + } + ownedRole.SetLabels(utillabels.AddLabel(ownedRole.GetLabels(), v1alpha1.CopiedLabelKey, operatorNamespace)) + if _, err := a.OpClient.CreateRole(ownedRole); err != nil { + return err + } + } + + ownedRoleBindings, err := a.lister.RbacV1().RoleBindingLister().RoleBindings(operatorNamespace).List(ownerSelector) + if err != nil { + return err + } + + targetRoleBindings, err := a.lister.RbacV1().RoleBindingLister().RoleBindings(targetNamespace).List(ownerutil.CSVOwnerSelector(targetCSV)) + if err != nil { + return err + } + + targetRoleBindingsByName := map[string]*rbacv1.RoleBinding{} + for _, r := range targetRoleBindings { + targetRoleBindingsByName[r.GetName()] = r + } + + // role bindings + for _, ownedRoleBinding := range ownedRoleBindings { + // don't trust the owner label + if !ownerutil.IsOwnedBy(ownedRoleBinding, csv) { + continue + } + _, ok := targetRolesByName[ownedRoleBinding.GetName()] + + // role binding exists + if ok { + // TODO: we should check if SA/role has changed + continue + } + + // role binding doesn't exist + // TODO: we can work around error cases here; if there's an un-owned role with a matching name we should generate instead + ownedRoleBinding.SetNamespace(targetNamespace) + ownedRoleBinding.SetOwnerReferences([]metav1.OwnerReference{ownerutil.NonBlockingOwner(targetCSV)}) + if err := ownerutil.AddOwnerLabels(ownedRoleBinding, targetCSV); err != nil { + return err + } + ownedRoleBinding.SetLabels(utillabels.AddLabel(ownedRoleBinding.GetLabels(), v1alpha1.CopiedLabelKey, operatorNamespace)) + if _, err := a.OpClient.CreateRoleBinding(ownedRoleBinding); err != nil { + return err + } + } + return nil +} + +func (a *Operator) ensureCSVsInNamespaces(csv *v1alpha1.ClusterServiceVersion, operatorGroup *v1.OperatorGroup, targets resolver.NamespaceSet) error { + namespaces, err := a.lister.CoreV1().NamespaceLister().List(labels.Everything()) + if err != nil { + return err + } + for _, ns := range namespaces { + if ns.GetName() == operatorGroup.Namespace { + continue + } + if targets.Contains(ns.GetName()) { + if err := a.copyToNamespace(csv, ns.GetName()); err != nil { + a.Log.WithError(err).Debug("error copying to target") + } + } else { + if err := a.pruneFromNamespace(operatorGroup.GetName(), ns.GetName()); err != nil { + a.Log.WithError(err).Debug("error pruning from old target") + } + } + } + + return nil +} + +func (a *Operator) copyToNamespace(csv *v1alpha1.ClusterServiceVersion, namespace string) error { + logger := a.Log.WithField("operator-ns", csv.GetNamespace()).WithField("target-ns", namespace) + newCSV := csv.DeepCopy() + delete(newCSV.Annotations, v1.OperatorGroupTargetsAnnotationKey) + + fetchedCSV, err := a.lister.OperatorsV1alpha1().ClusterServiceVersionLister().ClusterServiceVersions(namespace).Get(newCSV.GetName()) + + logger = logger.WithField("csv", csv.GetName()) + if fetchedCSV != nil { + logger.Debug("checking annotations") + + if !reflect.DeepEqual(a.copyOperatorGroupAnnotations(&fetchedCSV.ObjectMeta), a.copyOperatorGroupAnnotations(&newCSV.ObjectMeta)) { + // TODO: only copy over the opgroup annotations, not _all_ annotations + fetchedCSV.Annotations = newCSV.Annotations + fetchedCSV.SetLabels(utillabels.AddLabel(fetchedCSV.GetLabels(), v1alpha1.CopiedLabelKey, csv.GetNamespace())) + // CRs don't support strategic merge patching, but in the future if they do this should be updated to patch + logger.Debug("updating target CSV") + if _, err := a.client.OperatorsV1alpha1().ClusterServiceVersions(namespace).Update(fetchedCSV); err != nil { + logger.WithError(err).Error("update target CSV failed") + return err + } + } + + logger.Debug("checking status") + newCSV.Status = csv.Status + newCSV.Status.Reason = v1alpha1.CSVReasonCopied + newCSV.Status.Message = fmt.Sprintf("The operator is running in %s but is managing this namespace", csv.GetNamespace()) + + if !reflect.DeepEqual(fetchedCSV.Status, newCSV.Status) { + logger.Debug("updating status") + // Must use fetchedCSV because UpdateStatus(...) checks resource UID. + fetchedCSV.Status = newCSV.Status + fetchedCSV.Status.LastUpdateTime = timeNow() + if _, err := a.client.OperatorsV1alpha1().ClusterServiceVersions(namespace).UpdateStatus(fetchedCSV); err != nil { + logger.WithError(err).Error("status update for target CSV failed") + return err + } + } + + } else if k8serrors.IsNotFound(err) { + newCSV.SetNamespace(namespace) + newCSV.SetResourceVersion("") + newCSV.SetLabels(utillabels.AddLabel(newCSV.GetLabels(), v1alpha1.CopiedLabelKey, csv.GetNamespace())) + + logger.Debug("copying CSV to target") + createdCSV, err := a.client.OperatorsV1alpha1().ClusterServiceVersions(namespace).Create(newCSV) + if err != nil { + a.Log.Errorf("Create for new CSV failed: %v", err) + return err + } + createdCSV.Status.Reason = v1alpha1.CSVReasonCopied + createdCSV.Status.Message = fmt.Sprintf("The operator is running in %s but is managing this namespace", csv.GetNamespace()) + createdCSV.Status.LastUpdateTime = timeNow() + if _, err := a.client.OperatorsV1alpha1().ClusterServiceVersions(namespace).UpdateStatus(createdCSV); err != nil { + a.Log.Errorf("Status update for CSV failed: %v", err) + return err + } + + } else if err != nil { + logger.WithError(err).Error("couldn't get CSV") + return err + } + return nil +} + +func (a *Operator) pruneFromNamespace(operatorGroupName, namespace string) error { + fetchedCSVs, err := a.lister.OperatorsV1alpha1().ClusterServiceVersionLister().ClusterServiceVersions(namespace).List(labels.Everything()) + if err != nil { + return err + } + + for _, csv := range fetchedCSVs { + if csv.IsCopied() && csv.GetAnnotations()[v1.OperatorGroupAnnotationKey] == operatorGroupName { + a.Log.Debugf("Found CSV '%v' in namespace %v to delete", csv.GetName(), namespace) + a.gcQueueIndexer.Enqueue(csv) + } + } + return nil +} + +func (a *Operator) setOperatorGroupAnnotations(obj *metav1.ObjectMeta, op *v1.OperatorGroup, addTargets bool) { + metav1.SetMetaDataAnnotation(obj, v1.OperatorGroupNamespaceAnnotationKey, op.GetNamespace()) + metav1.SetMetaDataAnnotation(obj, v1.OperatorGroupAnnotationKey, op.GetName()) + + if addTargets && op.Status.Namespaces != nil { + metav1.SetMetaDataAnnotation(obj, v1.OperatorGroupTargetsAnnotationKey, op.BuildTargetNamespaces()) + } +} + +func (a *Operator) operatorGroupAnnotationsDiffer(obj *metav1.ObjectMeta, op *v1.OperatorGroup) bool { + annotations := obj.GetAnnotations() + if annotations == nil { + return true + } + if operatorGroupNamespace, ok := annotations[v1.OperatorGroupNamespaceAnnotationKey]; !ok || operatorGroupNamespace != op.GetNamespace() { + return true + } + if operatorGroup, ok := annotations[v1.OperatorGroupAnnotationKey]; !ok || operatorGroup != op.GetName() { + return true + } + if targets, ok := annotations[v1.OperatorGroupTargetsAnnotationKey]; !ok || targets != op.BuildTargetNamespaces() { + a.Log.WithFields(logrus.Fields{ + "annotationTargets": annotations[v1.OperatorGroupTargetsAnnotationKey], + "opgroupTargets": op.BuildTargetNamespaces(), + }).Debug("annotations different") + return true + } + + a.Log.WithFields(logrus.Fields{ + "annotationTargets": annotations[v1.OperatorGroupTargetsAnnotationKey], + "opgroupTargets": op.BuildTargetNamespaces(), + }).Debug("annotations correct") + return false +} + +func (a *Operator) copyOperatorGroupAnnotations(obj *metav1.ObjectMeta) map[string]string { + copiedAnnotations := make(map[string]string) + for k, v := range obj.GetAnnotations() { + switch k { + case v1.OperatorGroupNamespaceAnnotationKey: + fallthrough + case v1.OperatorGroupAnnotationKey: + fallthrough + case v1.OperatorGroupTargetsAnnotationKey: + copiedAnnotations[k] = v + } + } + return copiedAnnotations +} + +func namespacesChanged(clusterNamespaces []string, statusNamespaces []string) bool { + if len(clusterNamespaces) != len(statusNamespaces) { + return true + } + + nsMap := map[string]struct{}{} + for _, v := range clusterNamespaces { + nsMap[v] = struct{}{} + } + for _, v := range statusNamespaces { + if _, ok := nsMap[v]; !ok { + return true + } + } + return false +} + +func (a *Operator) getOperatorGroupTargets(op *v1.OperatorGroup) (map[string]struct{}, error) { + selector, err := metav1.LabelSelectorAsSelector(op.Spec.Selector) + + if err != nil { + return nil, err + } + + namespaceSet := make(map[string]struct{}) + if op.Spec.TargetNamespaces != nil && len(op.Spec.TargetNamespaces) > 0 { + for _, ns := range op.Spec.TargetNamespaces { + if ns == corev1.NamespaceAll { + return nil, fmt.Errorf("TargetNamespaces cannot contain NamespaceAll: %v", op.Spec.TargetNamespaces) + } + namespaceSet[ns] = struct{}{} + } + } else if selector == nil || selector.Empty() || selector == labels.Nothing() { + namespaceSet[corev1.NamespaceAll] = struct{}{} + } else { + matchedNamespaces, err := a.lister.CoreV1().NamespaceLister().List(selector) + if err != nil { + return nil, err + } + + for _, ns := range matchedNamespaces { + namespaceSet[ns.GetName()] = struct{}{} + } + } + return namespaceSet, nil +} + +func (a *Operator) updateNamespaceList(op *v1.OperatorGroup) ([]string, error) { + namespaceSet, err := a.getOperatorGroupTargets(op) + if err != nil { + return nil, err + } + namespaceList := []string{} + for ns := range namespaceSet { + namespaceList = append(namespaceList, ns) + } + + return namespaceList, nil +} + +func (a *Operator) ensureOpGroupClusterRole(op *v1.OperatorGroup, suffix string) error { + clusterRole := &rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: strings.Join([]string{op.GetName(), suffix}, "-"), + }, + AggregationRule: &rbacv1.AggregationRule{ + ClusterRoleSelectors: []metav1.LabelSelector{ + { + MatchLabels: map[string]string{ + operatorGroupAggregrationKeyPrefix + suffix: op.GetName(), + }, + }, + }, + }, + } + _, err := a.OpClient.KubernetesInterface().RbacV1().ClusterRoles().Create(clusterRole) + if k8serrors.IsAlreadyExists(err) { + return nil + } else if err != nil { + a.Log.WithError(err).Errorf("Create cluster role failed: %v", clusterRole) + return err + } + return nil +} + +func (a *Operator) ensureOpGroupClusterRoles(op *v1.OperatorGroup) error { + if err := a.ensureOpGroupClusterRole(op, AdminSuffix); err != nil { + return err + } + if err := a.ensureOpGroupClusterRole(op, EditSuffix); err != nil { + return err + } + if err := a.ensureOpGroupClusterRole(op, ViewSuffix); err != nil { + return err + } + return nil +} + +func (a *Operator) findCSVsThatProvideAnyOf(provide resolver.APISet) ([]*v1alpha1.ClusterServiceVersion, error) { + csvs, err := a.lister.OperatorsV1alpha1().ClusterServiceVersionLister().ClusterServiceVersions(metav1.NamespaceAll).List(labels.Everything()) + if err != nil { + return nil, err + } + + providers := []*v1alpha1.ClusterServiceVersion{} + for i := 0; i < len(csvs); i++ { + csv := csvs[i] + if csv.IsCopied() { + continue + } + + operatorSurface, err := resolver.NewOperatorFromCSV(csv) + if err != nil { + continue + } + + if len(operatorSurface.ProvidedAPIs().StripPlural().Intersection(provide)) > 0 { + providers = append(providers, csv) + } + } + + return providers, nil +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/olm/requirements.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/olm/requirements.go new file mode 100644 index 0000000000..44ae47367d --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/olm/requirements.go @@ -0,0 +1,405 @@ +package olm + +import ( + "encoding/json" + "fmt" + "strings" + + "github.com/sirupsen/logrus" + + "github.com/coreos/go-semver/semver" + "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + olmErrors "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/errors" + "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install" + "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func (a *Operator) minKubeVersionStatus(name string, minKubeVersion string) (met bool, statuses []v1alpha1.RequirementStatus) { + status := v1alpha1.RequirementStatus{ + Group: "operators.coreos.com", + Version: "v1alpha1", + Kind: "ClusterServiceVersion", + Name: name, + } + + if minKubeVersion == "" { + status.Status = v1alpha1.RequirementStatusReasonNotPresent + status.Message = "CSV missing minimum kube version specification" + met = true + statuses = append(statuses, status) + return + } + + // Retrieve server k8s version + serverVersionInfo, err := a.OpClient.KubernetesInterface().Discovery().ServerVersion() + if err != nil { + status.Status = v1alpha1.RequirementStatusReasonPresentNotSatisfied + status.Message = "Server version discovery error" + met = false + statuses = append(statuses, status) + return + } + + serverVersion, err := semver.NewVersion(strings.Split(strings.TrimPrefix(serverVersionInfo.String(), "v"), "-")[0]) + if err != nil { + status.Status = v1alpha1.RequirementStatusReasonPresentNotSatisfied + status.Message = "Server version parsing error" + met = false + statuses = append(statuses, status) + return + } + + csvVersionInfo, err := semver.NewVersion(strings.TrimPrefix(minKubeVersion, "v")) + if err != nil { + status.Status = v1alpha1.RequirementStatusReasonPresentNotSatisfied + status.Message = "CSV version parsing error" + met = false + statuses = append(statuses, status) + return + } + + if csvVersionInfo.Compare(*serverVersion) > 0 { + status.Status = v1alpha1.RequirementStatusReasonPresentNotSatisfied + status.Message = fmt.Sprintf("CSV version requirement not met: minKubeVersion (%s) > server version (%s)", minKubeVersion, serverVersion.String()) + met = false + statuses = append(statuses, status) + return + } + + status.Status = v1alpha1.RequirementStatusReasonPresent + status.Message = fmt.Sprintf("CSV minKubeVersion (%s) less than server version (%s)", minKubeVersion, serverVersionInfo.String()) + met = true + statuses = append(statuses, status) + return +} + +func (a *Operator) requirementStatus(strategyDetailsDeployment *install.StrategyDetailsDeployment, crdDescs []v1alpha1.CRDDescription, + ownedAPIServiceDescs []v1alpha1.APIServiceDescription, requiredAPIServiceDescs []v1alpha1.APIServiceDescription, + requiredNativeAPIs []metav1.GroupVersionKind) (met bool, statuses []v1alpha1.RequirementStatus) { + met = true + + // Check for CRDs + for _, r := range crdDescs { + status := v1alpha1.RequirementStatus{ + Group: "apiextensions.k8s.io", + Version: "v1beta1", + Kind: "CustomResourceDefinition", + Name: r.Name, + } + + // check if CRD exists - this verifies group, version, and kind, so no need for GVK check via discovery + crd, err := a.lister.APIExtensionsV1beta1().CustomResourceDefinitionLister().Get(r.Name) + if err != nil { + status.Status = v1alpha1.RequirementStatusReasonNotPresent + status.Message = "CRD is not present" + a.Log.Debugf("Setting 'met' to false, %v with status %v, with err: %v", r.Name, status, err) + met = false + statuses = append(statuses, status) + continue + } + + if crd.Spec.Version != r.Version { + served := false + for _, version := range crd.Spec.Versions { + if version.Name == r.Version { + if version.Served { + served = true + } + break + } + } + + if !served { + status.Status = v1alpha1.RequirementStatusReasonNotPresent + status.Message = "CRD version not served" + a.Log.Debugf("Setting 'met' to false, %v with status %v, CRD version %v not found", r.Name, status, r.Version) + met = false + statuses = append(statuses, status) + continue + } + } + + // Check if CRD has successfully registered with k8s API + established := false + namesAccepted := false + for _, cdt := range crd.Status.Conditions { + switch cdt.Type { + case v1beta1.Established: + if cdt.Status == v1beta1.ConditionTrue { + established = true + } + case v1beta1.NamesAccepted: + if cdt.Status == v1beta1.ConditionTrue { + namesAccepted = true + } + } + } + + if established && namesAccepted { + status.Status = v1alpha1.RequirementStatusReasonPresent + status.Message = "CRD is present and Established condition is true" + status.UUID = string(crd.GetUID()) + statuses = append(statuses, status) + } else { + status.Status = v1alpha1.RequirementStatusReasonNotAvailable + status.Message = "CRD is present but the Established condition is False (not available)" + met = false + a.Log.Debugf("Setting 'met' to false, %v with status %v, established=%v, namesAccepted=%v", r.Name, status, established, namesAccepted) + statuses = append(statuses, status) + } + } + + // Check for required API services + for _, r := range requiredAPIServiceDescs { + name := fmt.Sprintf("%s.%s", r.Version, r.Group) + status := v1alpha1.RequirementStatus{ + Group: "apiregistration.k8s.io", + Version: "v1", + Kind: "APIService", + Name: name, + } + + // Check if GVK exists + if err := a.isGVKRegistered(r.Group, r.Version, r.Kind); err != nil { + status.Status = "NotPresent" + met = false + statuses = append(statuses, status) + continue + } + + // Check if APIService is registered + apiService, err := a.lister.APIRegistrationV1().APIServiceLister().Get(name) + if err != nil { + status.Status = "NotPresent" + met = false + statuses = append(statuses, status) + continue + } + + // Check if API is available + if !a.isAPIServiceAvailable(apiService) { + status.Status = "NotPresent" + met = false + } else { + status.Status = "Present" + status.UUID = string(apiService.GetUID()) + } + statuses = append(statuses, status) + } + + // Check owned API services + for _, r := range ownedAPIServiceDescs { + name := fmt.Sprintf("%s.%s", r.Version, r.Group) + status := v1alpha1.RequirementStatus{ + Group: "apiregistration.k8s.io", + Version: "v1", + Kind: "APIService", + Name: name, + } + + found := false + for _, spec := range strategyDetailsDeployment.DeploymentSpecs { + if spec.Name == r.DeploymentName { + status.Status = "DeploymentFound" + statuses = append(statuses, status) + found = true + break + } + } + + if !found { + status.Status = "DeploymentNotFound" + statuses = append(statuses, status) + met = false + } + } + + for _, r := range requiredNativeAPIs { + name := fmt.Sprintf("%s.%s", r.Version, r.Group) + status := v1alpha1.RequirementStatus{ + Group: r.Group, + Version: r.Version, + Kind: r.Kind, + Name: name, + } + + if err := a.isGVKRegistered(r.Group, r.Version, r.Kind); err != nil { + status.Status = v1alpha1.RequirementStatusReasonNotPresent + status.Message = "Native API does not exist" + met = false + statuses = append(statuses, status) + continue + } else { + status.Status = v1alpha1.RequirementStatusReasonPresent + status.Message = "Native API exists" + statuses = append(statuses, status) + continue + } + } + + return +} + +// permissionStatus checks whether the given CSV's RBAC requirements are met in its namespace +func (a *Operator) permissionStatus(strategyDetailsDeployment *install.StrategyDetailsDeployment, ruleChecker install.RuleChecker, csvNamespace string) (bool, []v1alpha1.RequirementStatus, error) { + statusesSet := map[string]v1alpha1.RequirementStatus{} + + checkPermissions := func(permissions []install.StrategyDeploymentPermissions, namespace string) (bool, error) { + met := true + for _, perm := range permissions { + saName := perm.ServiceAccountName + a.Log.Debugf("perm.ServiceAccountName: %s", saName) + + var status v1alpha1.RequirementStatus + if stored, ok := statusesSet[saName]; !ok { + status = v1alpha1.RequirementStatus{ + Group: "", + Version: "v1", + Kind: "ServiceAccount", + Name: saName, + Status: v1alpha1.RequirementStatusReasonPresent, + Dependents: []v1alpha1.DependentStatus{}, + } + } else { + status = stored + } + + // Ensure the ServiceAccount exists + sa, err := a.OpClient.GetServiceAccount(csvNamespace, perm.ServiceAccountName) + if err != nil { + met = false + status.Status = v1alpha1.RequirementStatusReasonNotPresent + status.Message = "Service account does not exist" + statusesSet[saName] = status + continue + } + + // Check if PolicyRules are satisfied + for _, rule := range perm.Rules { + dependent := v1alpha1.DependentStatus{ + Group: "rbac.authorization.k8s.io", + Kind: "PolicyRule", + Version: "v1beta1", + } + + marshalled, err := json.Marshal(rule) + if err != nil { + dependent.Status = v1alpha1.DependentStatusReasonNotSatisfied + dependent.Message = "rule unmarshallable" + status.Dependents = append(status.Dependents, dependent) + continue + } + + var scope string + if namespace == metav1.NamespaceAll { + scope = "cluster" + } else { + scope = "namespaced" + } + dependent.Message = fmt.Sprintf("%s rule:%s", scope, marshalled) + + satisfied, err := ruleChecker.RuleSatisfied(sa, namespace, rule) + if err != nil { + return false, err + } else if !satisfied { + met = false + dependent.Status = v1alpha1.DependentStatusReasonNotSatisfied + status.Status = v1alpha1.RequirementStatusReasonPresentNotSatisfied + status.Message = "Policy rule not satisfied for service account" + } else { + dependent.Status = v1alpha1.DependentStatusReasonSatisfied + } + + status.Dependents = append(status.Dependents, dependent) + } + + statusesSet[saName] = status + } + + return met, nil + } + + permMet, err := checkPermissions(strategyDetailsDeployment.Permissions, csvNamespace) + if err != nil { + return false, nil, err + } + clusterPermMet, err := checkPermissions(strategyDetailsDeployment.ClusterPermissions, metav1.NamespaceAll) + if err != nil { + return false, nil, err + } + + statuses := []v1alpha1.RequirementStatus{} + for key, status := range statusesSet { + a.Log.Debugf("appending permission status: %s", key) + statuses = append(statuses, status) + } + + return permMet && clusterPermMet, statuses, nil +} + +// requirementAndPermissionStatus returns the aggregate requirement and permissions statuses for the given CSV +func (a *Operator) requirementAndPermissionStatus(csv *v1alpha1.ClusterServiceVersion) (bool, []v1alpha1.RequirementStatus, error) { + // Use a StrategyResolver to unmarshal + strategyResolver := install.StrategyResolver{} + strategy, err := strategyResolver.UnmarshalStrategy(csv.Spec.InstallStrategy) + if err != nil { + return false, nil, err + } + + // Assume the strategy is for a deployment + strategyDetailsDeployment, ok := strategy.(*install.StrategyDetailsDeployment) + if !ok { + return false, nil, fmt.Errorf("could not cast install strategy as type %T", strategyDetailsDeployment) + } + + // Check kubernetes version requirement between CSV and server + minKubeMet, minKubeStatus := a.minKubeVersionStatus(csv.GetName(), csv.Spec.MinKubeVersion) + reqMet, reqStatuses := a.requirementStatus(strategyDetailsDeployment, csv.GetAllCRDDescriptions(), csv.GetOwnedAPIServiceDescriptions(), csv.GetRequiredAPIServiceDescriptions(), csv.Spec.NativeAPIs) + allReqStatuses := append(minKubeStatus, reqStatuses...) + + rbacLister := a.lister.RbacV1() + roleLister := rbacLister.RoleLister() + roleBindingLister := rbacLister.RoleBindingLister() + clusterRoleLister := rbacLister.ClusterRoleLister() + clusterRoleBindingLister := rbacLister.ClusterRoleBindingLister() + + ruleChecker := install.NewCSVRuleChecker(roleLister, roleBindingLister, clusterRoleLister, clusterRoleBindingLister, csv) + permMet, permStatuses, err := a.permissionStatus(strategyDetailsDeployment, ruleChecker, csv.GetNamespace()) + if err != nil { + return false, nil, err + } + + // Aggregate requirement and permissions statuses + statuses := append(allReqStatuses, permStatuses...) + met := minKubeMet && reqMet && permMet + if !met { + a.Log.WithField("minKubeMet", minKubeMet).WithField("reqMet", reqMet).WithField("permMet", permMet).Debug("permissions/requirements not met") + } + + return met, statuses, nil +} + +func (a *Operator) isGVKRegistered(group, version, kind string) error { + logger := a.Log.WithFields(logrus.Fields{ + "group": group, + "version": version, + "kind": kind, + }) + + gv := metav1.GroupVersion{Group: group, Version: version} + resources, err := a.OpClient.KubernetesInterface().Discovery().ServerResourcesForGroupVersion(gv.String()) + if err != nil { + logger.WithField("err", err).Info("could not query for GVK in api discovery") + return err + } + + for _, r := range resources.APIResources { + if r.Kind == kind { + return nil + } + } + + logger.Info("couldn't find GVK in api discovery") + return olmErrors.GroupVersionKindNotFoundError{group, version, kind} +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/configmap_loader.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/configmap_loader.go deleted file mode 100644 index 209cbaa8aa..0000000000 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/configmap_loader.go +++ /dev/null @@ -1,123 +0,0 @@ -package registry - -import ( - "encoding/json" - "fmt" - - "github.com/ghodss/yaml" - log "github.com/sirupsen/logrus" - "k8s.io/api/core/v1" - "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" - "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient" -) - -const ( - ConfigMapCRDName = "customResourceDefinitions" - ConfigMapCSVName = "clusterServiceVersions" - ConfigMapPackageName = "packages" -) - -// ConfigMapCatalogResourceLoader loads a ConfigMap of resources into the in-memory catalog -type ConfigMapCatalogResourceLoader struct { - namespace string - opClient operatorclient.ClientInterface -} - -func NewConfigMapCatalogResourceLoader(namespace string, opClient operatorclient.ClientInterface) ConfigMapCatalogResourceLoader { - return ConfigMapCatalogResourceLoader{ - namespace: namespace, - opClient: opClient, - } -} - -func (d *ConfigMapCatalogResourceLoader) LoadCatalogResources(catalog *InMem, configMapName string) error { - log.Debugf("Load ConfigMap -- BEGIN %s", configMapName) - - cm, err := d.opClient.KubernetesInterface().CoreV1().ConfigMaps(d.namespace).Get(configMapName, metav1.GetOptions{}) - if err != nil { - log.Debugf("Load ConfigMap -- ERROR %s : error=%s", configMapName, err) - return fmt.Errorf("error loading catalog from ConfigMap %s: %s", configMapName, err) - } - return d.LoadCatalogResourcesFromConfigMap(catalog, cm) -} - -func (d *ConfigMapCatalogResourceLoader) LoadCatalogResourcesFromConfigMap(catalog *InMem, cm *v1.ConfigMap) error { - configMapName := cm.GetName() - found := false - crdListYaml, ok := cm.Data[ConfigMapCRDName] - if ok { - crdListJson, err := yaml.YAMLToJSON([]byte(crdListYaml)) - if err != nil { - log.Debugf("Load ConfigMap -- ERROR %s : error=%s", configMapName, err) - return fmt.Errorf("error loading CRD list yaml from ConfigMap %s: %s", configMapName, err) - } - - var parsedCRDList []v1beta1.CustomResourceDefinition - err = json.Unmarshal([]byte(crdListJson), &parsedCRDList) - if err != nil { - log.Debugf("Load ConfigMap -- ERROR %s : error=%s", configMapName, err) - return fmt.Errorf("error parsing CRD list (json) from ConfigMap %s: %s", configMapName, err) - } - - for _, crd := range parsedCRDList { - found = true - catalog.SetCRDDefinition(crd) - } - } - - csvListYaml, ok := cm.Data[ConfigMapCSVName] - if ok { - csvListJson, err := yaml.YAMLToJSON([]byte(csvListYaml)) - if err != nil { - log.Debugf("Load ConfigMap -- ERROR %s : error=%s", configMapName, err) - return fmt.Errorf("error loading CSV list yaml from ConfigMap %s: %s", configMapName, err) - } - - var parsedCSVList []v1alpha1.ClusterServiceVersion - err = json.Unmarshal([]byte(csvListJson), &parsedCSVList) - if err != nil { - log.Debugf("Load ConfigMap -- ERROR %s : error=%s", configMapName, err) - return fmt.Errorf("error parsing CSV list (json) from ConfigMap %s: %s", configMapName, err) - } - - for _, csv := range parsedCSVList { - found = true - catalog.setCSVDefinition(csv) - } - } - - packageListYaml, ok := cm.Data[ConfigMapPackageName] - if ok { - log.Debug("Load ConfigMap -- ConfigMap contains packages") - packageListJson, err := yaml.YAMLToJSON([]byte(packageListYaml)) - if err != nil { - log.Debugf("Load ConfigMap -- ERROR %s : error=%s", configMapName, err) - return fmt.Errorf("error loading package list yaml from ConfigMap %s: %s", configMapName, err) - } - - var parsedPackageManifests []PackageManifest - err = json.Unmarshal([]byte(packageListJson), &parsedPackageManifests) - if err != nil { - log.Debugf("Load ConfigMap -- ERROR %s : error=%s", configMapName, err) - return fmt.Errorf("error parsing package list (json) from ConfigMap %s: %s", configMapName, err) - } - for _, packageManifest := range parsedPackageManifests { - found = true - if err := catalog.AddPackageManifest(packageManifest); err != nil { - return err - } - } - log.Debugf("Load ConfigMap -- Found packages: %v", catalog.packages) - } - - if !found { - log.Debugf("Load ConfigMap -- ERROR %s : no resources found", configMapName) - return fmt.Errorf("error parsing ConfigMap %s: no valid resources found", configMapName) - } - - log.Debugf("Load ConfigMap -- OK %s", configMapName) - return nil -} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/directory_loader.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/directory_loader.go deleted file mode 100644 index e032263f90..0000000000 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/directory_loader.go +++ /dev/null @@ -1,120 +0,0 @@ -package registry - -import ( - "fmt" - "os" - "path/filepath" - "strings" - - log "github.com/sirupsen/logrus" -) - -// DirectoryCatalogResourceLoader loads a directory of resources into the in-memory catalog -// files ending in `.crd.yaml` will be parsed as CRDs -// files ending in`.clusterserviceversion.yaml` will be parsed as CRDs -type DirectoryCatalogResourceLoader struct { - Catalog *InMem -} - -func (d *DirectoryCatalogResourceLoader) LoadCatalogResources(directory string) error { - log.Debugf("Load Dir -- BEGIN %s", directory) - if err := filepath.Walk(directory, d.LoadCRDsWalkFunc); err != nil { - log.Debugf("Load Dir -- ERROR %s : CRD error=%s", directory, err) - return fmt.Errorf("error loading CRDs from directory %s: %s", directory, err) - } - if err := filepath.Walk(directory, d.LoadCSVsWalkFunc); err != nil { - log.Debugf("Load Dir -- ERROR %s : CSV error=%s", directory, err) - return fmt.Errorf("error loading CSVs from directory %s: %s", directory, err) - } - if err := filepath.Walk(directory, d.LoadPackagesWalkFunc); err != nil { - log.Debugf("Load Dir -- ERROR %s : PKG error=%s", directory, err) - return fmt.Errorf("error loading Packages from directory %s: %s", directory, err) - } - log.Debugf("Load Dir -- OK %s", directory) - return nil -} - -func (d *DirectoryCatalogResourceLoader) LoadCRDsWalkFunc(path string, f os.FileInfo, err error) error { - log.Debugf("Load CRD -- BEGIN %s", path) - if f == nil { - return fmt.Errorf("Not a valid file") - } - if f.IsDir() { - log.Debugf("Load CRD -- ISDIR %s", path) - if strings.HasPrefix(f.Name(), ".") { - log.Debugf("Load CRD -- SKIPHIDDEN %s", path) - return filepath.SkipDir - } - return nil - } - if strings.HasPrefix(f.Name(), ".") { - log.Debugf("Load CRD -- SKIPHIDDEN %s", path) - return nil - } - if strings.HasSuffix(path, ".crd.yaml") { - crd, err := LoadCRDFromFile(d.Catalog, path) - if err != nil { - log.Debugf("Load CRD -- ERROR %s", path) - return err - } - log.Debugf("Load CRD -- OK %s", crd.Name) - } - log.Debugf("Load CRD -- NO OP %s", path) - return nil -} - -func (d *DirectoryCatalogResourceLoader) LoadCSVsWalkFunc(path string, f os.FileInfo, err error) error { - log.Debugf("Load CSV -- BEGIN %s", path) - if f == nil { - return fmt.Errorf("Not a valid file") - } - if f.IsDir() { - if strings.HasPrefix(f.Name(), ".") { - log.Debugf("Load CSV -- SKIPHIDDEN %s", path) - return filepath.SkipDir - } - log.Debugf("Load CSV -- ISDIR %s", path) - return nil - } - if strings.HasPrefix(f.Name(), ".") { - log.Debugf("Load CSV -- SKIPHIDDEN %s", path) - return nil - } - if strings.HasSuffix(path, ".clusterserviceversion.yaml") { - csv, err := LoadCSVFromFile(d.Catalog, path) - if err != nil { - log.Debugf("Load CSV -- ERROR %s", path) - return err - } - log.Debugf("Load CSV -- OK %s", csv.Name) - } - return nil -} - -func (d *DirectoryCatalogResourceLoader) LoadPackagesWalkFunc(path string, f os.FileInfo, err error) error { - log.Debugf("Load Package -- BEGIN %s", path) - if f == nil { - return fmt.Errorf("Not a valid file") - } - if f.IsDir() { - if strings.HasPrefix(f.Name(), ".") { - log.Debugf("Load Package -- SKIPHIDDEN %s", path) - return filepath.SkipDir - } - log.Debugf("Load Package -- ISDIR %s", path) - return nil - } - if strings.HasPrefix(f.Name(), ".") { - log.Debugf("Load Package -- SKIPHIDDEN %s", path) - return nil - } - if strings.HasSuffix(path, ".package.yaml") { - pkg, err := LoadPackageFromFile(d.Catalog, path) - if err != nil { - log.Debugf("Load Package -- ERROR %s", path) - return err - } - log.Debugf("Load Package -- OK %s", pkg.PackageName) - } - return nil -} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/manifest.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/manifest.go deleted file mode 100644 index 29187fc9e4..0000000000 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/manifest.go +++ /dev/null @@ -1,68 +0,0 @@ -package registry - -import ( - "fmt" - "io/ioutil" - - "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" - "k8s.io/client-go/kubernetes/scheme" - - "encoding/json" - - "github.com/ghodss/yaml" - "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" -) - -// LoadCRDFromFile is a utility function for loading the CRD schemas. -func LoadCRDFromFile(m *InMem, filepath string) (*v1beta1.CustomResourceDefinition, error) { - data, err := ioutil.ReadFile(filepath) - if err != nil { - return nil, fmt.Errorf("unable to load CRD from file %s: %v", filepath, err) - } - crd := v1beta1.CustomResourceDefinition{} - if _, _, err = scheme.Codecs.UniversalDecoder().Decode(data, nil, &crd); err != nil { - return nil, fmt.Errorf("could not decode contents of file %s into CRD: %v", filepath, err) - } - if err = m.SetCRDDefinition(crd); err != nil { - return nil, fmt.Errorf("unable to set CRD found in catalog: %v", err) - } - return &crd, nil -} - -// LoadCSVFromFile is a utility function for loading CSV definitions -func LoadCSVFromFile(m *InMem, filepath string) (*v1alpha1.ClusterServiceVersion, error) { - data, err := ioutil.ReadFile(filepath) - if err != nil { - return nil, fmt.Errorf("unable to load CSV from file %s: %v", filepath, err) - } - csv := v1alpha1.ClusterServiceVersion{} - if _, _, err = scheme.Codecs.UniversalDecoder().Decode(data, nil, &csv); err != nil { - return nil, fmt.Errorf("could not decode contents of file %s into CSV: %v", filepath, err) - } - if err = m.setCSVDefinition(csv); err != nil { - return nil, fmt.Errorf("unable to set CSV found in catalog: %v", err) - } - return &csv, nil -} - -// LoadPackageFromFile is a utility function for loading Package definitions -func LoadPackageFromFile(m *InMem, filepath string) (*PackageManifest, error) { - data, err := ioutil.ReadFile(filepath) - if err != nil { - return nil, fmt.Errorf("unable to load package from file %s: %v", filepath, err) - } - pkg := PackageManifest{} - - packageJson, err := yaml.YAMLToJSON(data) - - if err != nil { - return nil, fmt.Errorf("error loading package yaml: %s", err) - } - - err = json.Unmarshal([]byte(packageJson), &pkg) - - if err = m.AddPackageManifest(pkg); err != nil { - return nil, fmt.Errorf("unable to set package found in catalog: %v", err) - } - return &pkg, nil -} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/mem.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/mem.go deleted file mode 100644 index 41f624dda9..0000000000 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/mem.go +++ /dev/null @@ -1,435 +0,0 @@ -package registry - -import ( - "fmt" - - log "github.com/sirupsen/logrus" - "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" - "k8s.io/apimachinery/pkg/api/equality" - - "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" - "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient" -) - -// InMem - catalog source implementation that stores the data in memory in golang maps -var _ Source = &InMem{} - -type InMem struct { - // map ClusterServiceVersion name to their resource definition - clusterservices map[string]v1alpha1.ClusterServiceVersion - - // map ClusterServiceVersions by name to metadata for the CSV that replaces it - replaces map[string][]CSVMetadata - - // map CRD to their full definition - crds map[CRDKey]v1beta1.CustomResourceDefinition - - // map CRD to the names of the CSVs that own them - crdOwners map[CRDKey][]string - - // map package name to their full manifest - packages map[string]PackageManifest - - // map from CSV name to the package channel(s) that contain it. - csvPackageChannels map[string][]packageAndChannel -} - -type packageAndChannel struct { - packageRef PackageManifest - channelRef PackageChannel -} - -func NewInMemoryFromDirectory(directory string) (*InMem, error) { - log.Infof("loading catalog from directory: %s", directory) - loader := DirectoryCatalogResourceLoader{NewInMem()} - if err := loader.LoadCatalogResources(directory); err != nil { - return nil, err - } - return loader.Catalog, nil -} - -func NewInMemoryFromConfigMap(cmClient operatorclient.ClientInterface, namespace, cmName string) (*InMem, error) { - log.Infof("loading catalog from a configmap: %s", cmName) - loader := ConfigMapCatalogResourceLoader{namespace, cmClient} - catalog := NewInMem() - if err := loader.LoadCatalogResources(catalog, cmName); err != nil { - return nil, err - } - return catalog, nil -} - -// NewInMem returns a ptr to a new InMem instance -func NewInMem() *InMem { - return &InMem{ - clusterservices: map[string]v1alpha1.ClusterServiceVersion{}, - replaces: map[string][]CSVMetadata{}, - crds: map[CRDKey]v1beta1.CustomResourceDefinition{}, - crdOwners: map[CRDKey][]string{}, - packages: map[string]PackageManifest{}, - csvPackageChannels: map[string][]packageAndChannel{}, - } -} - -// SetCRDDefinition sets the full resource definition of a CRD in the stored map -// only sets a new definition if one is not already set -func (m *InMem) SetCRDDefinition(crd v1beta1.CustomResourceDefinition) error { - key := CRDKey{ - Kind: crd.Spec.Names.Kind, - Name: crd.GetName(), - Version: crd.Spec.Version, - } - if old, exists := m.crds[key]; exists && !equality.Semantic.DeepEqual(crd, old) { - return fmt.Errorf("invalid CRD : definition for CRD %s already set", crd.GetName()) - } - m.crds[key] = crd - return nil -} - -// FindReplacementCSVForPackageNameUnderChannel returns the CSV that replaces the CSV with the -// matching CSV name, within the package and channel specified. -func (m *InMem) FindReplacementCSVForPackageNameUnderChannel(packageName string, channelName string, csvName string) (*v1alpha1.ClusterServiceVersion, error) { - latestCSV, err := m.FindCSVForPackageNameUnderChannel(packageName, channelName) - if err != nil { - return nil, err - } - - if latestCSV.GetName() == csvName { - return nil, fmt.Errorf("Channel is already up-to-date") - } - - // Walk backwards over the `replaces` field until we find the CSV with the specified name. - var currentCSV = latestCSV - var nextCSV *v1alpha1.ClusterServiceVersion = nil - for currentCSV != nil { - if currentCSV.GetName() == csvName { - return nextCSV, nil - } - - nextCSV = currentCSV - replacesName := currentCSV.Spec.Replaces - currentCSV = nil - - if replacesName != "" { - replacesCSV, err := m.FindCSVByName(replacesName) - if err != nil { - return nil, err - } - - currentCSV = replacesCSV - } - } - - return nil, fmt.Errorf("Could not find matching replacement for CSV `%s` in package `%s` for channel `%s`", csvName, packageName, channelName) -} - -// FindCSVForPackageNameUnderChannel finds the CSV referenced by the specified channel under the -// package with the specified name. -func (m *InMem) FindCSVForPackageNameUnderChannel(packageName string, channelName string) (*v1alpha1.ClusterServiceVersion, error) { - packageManifest, ok := m.packages[packageName] - if !ok { - return nil, fmt.Errorf("Unknown package %s", packageName) - } - - for _, channel := range packageManifest.Channels { - if channel.Name == channelName { - return m.FindCSVByName(channel.CurrentCSVName) - } - } - - return nil, fmt.Errorf("Unknown channel %s in package %s", channelName, packageName) -} - -// addPackageManifest adds a new package manifest to the in memory catalog. -func (m *InMem) AddPackageManifest(pkg PackageManifest) error { - if len(pkg.PackageName) == 0 { - return fmt.Errorf("Empty package name") - } - - // Make sure that each channel name is unique and that the referenced CSV exists. - channelMap := make(map[string]bool, len(pkg.Channels)) - for _, channel := range pkg.Channels { - if _, exists := channelMap[channel.Name]; exists { - return fmt.Errorf("Channel %s declared twice in package manifest", channel.Name) - } - - channelMap[channel.Name] = true - - currentCSV, err := m.FindCSVByName(channel.CurrentCSVName) - if err != nil { - return fmt.Errorf("Missing CSV with name %s", channel.CurrentCSVName) - } - - // For each of the CSVs in the full replacement chain, add an entry to the package map. - csvChain, err := m.fullCSVReplacesHistory(currentCSV) - if err != nil { - return err - } - - for _, csv := range csvChain { - if _, ok := m.csvPackageChannels[csv.GetName()]; !ok { - m.csvPackageChannels[csv.GetName()] = []packageAndChannel{} - } - - m.csvPackageChannels[csv.GetName()] = append(m.csvPackageChannels[csv.GetName()], packageAndChannel{ - packageRef: pkg, - channelRef: channel, - }) - } - } - - // Make sure the default channel name matches a real channel, if given. - if pkg.DefaultChannelName != "" { - if _, exists := channelMap[pkg.DefaultChannelName]; !exists { - return fmt.Errorf("Invalid default channel %s", pkg.DefaultChannelName) - } - } - - m.packages[pkg.PackageName] = pkg - return nil -} - -// fullCSVHistory returns the full set of CSVs in the `replaces` history, starting at the given CSV. -func (m *InMem) fullCSVReplacesHistory(csv *v1alpha1.ClusterServiceVersion) ([]v1alpha1.ClusterServiceVersion, error) { - if csv.Spec.Replaces == "" { - return []v1alpha1.ClusterServiceVersion{*csv}, nil - } - - replaced, err := m.FindCSVByName(csv.Spec.Replaces) - if err != nil { - return []v1alpha1.ClusterServiceVersion{}, err - } - - replacedChain, err := m.fullCSVReplacesHistory(replaced) - if err != nil { - return []v1alpha1.ClusterServiceVersion{}, err - } - - return append(replacedChain, *csv), nil -} - -// setOrReplaceCRDDefinition overwrites any existing definition with the same name -func (m *InMem) setOrReplaceCRDDefinition(crd v1beta1.CustomResourceDefinition) { - m.crds[CRDKey{ - Kind: crd.Spec.Names.Kind, - Name: crd.GetName(), - Version: crd.Spec.Version, - }] = crd -} - -// findServiceConflicts collates a list of errors from conflicting catalog entries -func (m *InMem) findServiceConflicts(csv v1alpha1.ClusterServiceVersion) []error { - errs := []error{} - - // validate owned CRDs - for _, crdReq := range csv.Spec.CustomResourceDefinitions.Owned { - key := CRDKey{ - Kind: crdReq.Kind, - Name: crdReq.Name, - Version: crdReq.Version, - } - // validate crds have definitions stored - if _, ok := m.crds[key]; !ok { - errs = append(errs, fmt.Errorf("missing definition for owned CRD %v", key)) - } - } - return errs -} - -// addService is a helper fn to register a new service into the catalog -// will error if `safe` is true and conflicts are found -func (m *InMem) addService(csv v1alpha1.ClusterServiceVersion, safe bool) error { - name := csv.GetName() - - // find and log any conflicts; return with error if in `safe` mode - if conflicts := m.findServiceConflicts(csv); len(conflicts) > 0 { - log.Debugf("found conflicts for CSV %s: %v", name, conflicts) - if safe { - return fmt.Errorf("cannot add CSV %s safely: %v", name, conflicts) - } - } - - // add service - m.clusterservices[name] = csv - - // register it as replacing CSV from its spec, if any - if csv.Spec.Replaces != "" { - if _, ok := m.replaces[csv.Spec.Replaces]; !ok { - m.replaces[csv.Spec.Replaces] = []CSVMetadata{} - } - - m.replaces[csv.Spec.Replaces] = append(m.replaces[csv.Spec.Replaces], CSVMetadata{ - Name: name, - Version: csv.Spec.Version.String(), - }) - } - - // register its crds - for _, crd := range csv.Spec.CustomResourceDefinitions.Owned { - key := CRDKey{ - Name: crd.Name, - Version: crd.Version, - Kind: crd.Kind, - } - - if m.crdOwners[key] == nil { - m.crdOwners[key] = []string{} - } - - m.crdOwners[key] = append(m.crdOwners[key], name) - } - return nil -} - -// setCSVDefinition registers a new service into the catalog -// will return error if any conflicts exist -func (m *InMem) setCSVDefinition(csv v1alpha1.ClusterServiceVersion) error { - return m.addService(csv, true) -} - -// AddOrReplaceService registers service into the catalog, overwriting any existing values -func (m *InMem) AddOrReplaceService(csv v1alpha1.ClusterServiceVersion) { - _ = m.addService(csv, false) -} - -// removeService is a helper fn to delete a service from the catalog -func (m *InMem) removeService(name string) error { - csv, exists := m.clusterservices[name] - if !exists { - return fmt.Errorf("not found: ClusterServiceVersion %s", name) - } - - delete(m.clusterservices, name) - if csv.Spec.Replaces != "" { - delete(m.replaces, csv.Spec.Replaces) - } - - return nil -} - -// FindCSVByName looks up the CSV with the given name. -func (m *InMem) FindCSVByName(name string) (*v1alpha1.ClusterServiceVersion, error) { - csv, exists := m.clusterservices[name] - if !exists { - return nil, fmt.Errorf("not found: ClusterServiceVersion %s", name) - } - - return &csv, nil -} - -// FindReplacementCSVForName looks up any CSV in the catalog that replaces the given CSV, if any. -func (m *InMem) FindReplacementCSVForName(name string) (*v1alpha1.ClusterServiceVersion, error) { - csvMetadata, ok := m.replaces[name] - if !ok { - return nil, fmt.Errorf("not found: ClusterServiceVersion that replaces %s", name) - } - - if len(csvMetadata) < 1 { - return nil, fmt.Errorf("not found: ClusterServiceVersion that replaces %s", name) - } - - return m.FindCSVByName(csvMetadata[0].Name) -} - -// AllPackages returns all package manifests in the catalog -func (m *InMem) AllPackages() map[string]PackageManifest { - return m.packages -} - -// ListServices lists all versions of the service in the catalog -func (m *InMem) ListServices() ([]v1alpha1.ClusterServiceVersion, error) { - services := []v1alpha1.ClusterServiceVersion{} - for _, csv := range m.clusterservices { - services = append(services, csv) - } - return services, nil -} - -// ListLatestCSVsForCRD lists the latests versions of the service that manages the given CRD. -func (m *InMem) ListLatestCSVsForCRD(key CRDKey) ([]CSVAndChannelInfo, error) { - // Find the names of the CSVs that own the CRD. - ownerCSVNames, ok := m.crdOwners[key] - if !ok { - return nil, fmt.Errorf("not found: CRD %s", key) - } - - // For each of the CSVs found, lookup the package channels that create that CSV somewhere along - // the way. For each, we then filter to the latest CSV that creates the CRD, and return that. - // This allows the caller to find the *latest* version of each channel, that will successfully - // instantiate the require CRD. - channelInfo := make([]CSVAndChannelInfo, 0, len(ownerCSVNames)) - added := map[string]bool{} - - for _, ownerCSVName := range ownerCSVNames { - packageChannels, ok := m.csvPackageChannels[ownerCSVName] - if !ok { - // Note: legacy handling. To be removed once all CSVs are part of packages. - latestCSV, err := m.findLatestCSVThatOwns(ownerCSVName, key) - if err != nil { - return nil, err - } - - channelInfo = append(channelInfo, CSVAndChannelInfo{ - CSV: latestCSV, - Channel: PackageChannel{}, - IsDefaultChannel: false, - }) - continue - } - - for _, packageChannel := range packageChannels { - // Find the latest CSV in the channel that owns the CRD. - latestCSV, err := m.findLatestCSVThatOwns(packageChannel.channelRef.CurrentCSVName, key) - if err != nil { - return nil, err - } - - key := fmt.Sprintf("%s::%s", latestCSV.GetName(), packageChannel.channelRef.Name) - if _, ok := added[key]; ok { - continue - } - - channelInfo = append(channelInfo, CSVAndChannelInfo{ - CSV: latestCSV, - Channel: packageChannel.channelRef, - IsDefaultChannel: packageChannel.channelRef.IsDefaultChannel(packageChannel.packageRef), - }) - added[key] = true - } - } - - return channelInfo, nil -} - -// findLatestCSVThatOwns returns the latest CSV in the chain of CSVs, starting at the CSV with the -// specified name, that owns the referenced CRD. For example, if given CSV `foobar-v1.2.0` in the -// a chain of foobar-v1.2.0 --(replaces)--> foobar-v1.1.0 --(replaces)--> foobar-v1.0.0 and -// `foobar-v1.1.0` is the latest that owns the CRD, it will be returned. -func (m *InMem) findLatestCSVThatOwns(csvName string, key CRDKey) (*v1alpha1.ClusterServiceVersion, error) { - csv, err := m.FindCSVByName(csvName) - if err != nil { - return nil, err - } - - // Check if the CSV owns the CRD. - for _, crdReq := range csv.Spec.CustomResourceDefinitions.Owned { - if crdReq.Name == key.Name { - return csv, nil - } - } - - // Otherwise, check the CSV this CSV replaces. - if csv.Spec.Replaces == "" { - return nil, fmt.Errorf("Could not find owner for CRD %s", key.Name) - } - - return m.findLatestCSVThatOwns(csv.Spec.Replaces, key) -} - -// FindCRDByName looks up the full CustomResourceDefinition for the resource with the given name -func (m *InMem) FindCRDByKey(key CRDKey) (*v1beta1.CustomResourceDefinition, error) { - crd, ok := m.crds[key] - if !ok { - return nil, fmt.Errorf("not found: CRD %s", key) - } - return &crd, nil -} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/reconciler/configmap.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/reconciler/configmap.go new file mode 100644 index 0000000000..4af7103092 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/reconciler/configmap.go @@ -0,0 +1,405 @@ +//go:generate counterfeiter -o ../../../fakes/fake_reconciler.go . RegistryReconciler +package reconciler + +import ( + "fmt" + "time" + + "github.com/pkg/errors" + "github.com/sirupsen/logrus" + "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/util/intstr" + + "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient" + "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister" + "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil" +) + +var timeNow = func() metav1.Time { return metav1.NewTime(time.Now().UTC()) } + +// configMapCatalogSourceDecorator wraps CatalogSource to add additional methods +type configMapCatalogSourceDecorator struct { + *v1alpha1.CatalogSource +} + +func (s *configMapCatalogSourceDecorator) serviceAccountName() string { + return s.GetName() + "-configmap-server" +} + +func (s *configMapCatalogSourceDecorator) roleName() string { + return s.GetName() + "-configmap-reader" +} + +func (s *configMapCatalogSourceDecorator) Selector() map[string]string { + return map[string]string{ + "olm.catalogSource": s.GetName(), + } +} + +func (s *configMapCatalogSourceDecorator) Labels() map[string]string { + labels := map[string]string{ + "olm.catalogSource": s.GetName(), + } + if s.Spec.SourceType == v1alpha1.SourceTypeInternal || s.Spec.SourceType == v1alpha1.SourceTypeConfigmap { + labels["olm.configMapResourceVersion"] = s.Status.ConfigMapResource.ResourceVersion + } + return labels +} + +func (s *configMapCatalogSourceDecorator) ConfigMapChanges(configMap *v1.ConfigMap) bool { + if s.Status.ConfigMapResource == nil { + return true + } + if s.Status.ConfigMapResource.ResourceVersion == configMap.GetResourceVersion() { + return false + } + return true +} + +func (s *configMapCatalogSourceDecorator) Service() *v1.Service { + svc := &v1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: s.GetName(), + Namespace: s.GetNamespace(), + }, + Spec: v1.ServiceSpec{ + Ports: []v1.ServicePort{ + { + Name: "grpc", + Port: 50051, + TargetPort: intstr.FromInt(50051), + }, + }, + Selector: s.Selector(), + }, + } + ownerutil.AddOwner(svc, s.CatalogSource, false, false) + return svc +} + +func (s *configMapCatalogSourceDecorator) Pod(image string) *v1.Pod { + pod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + GenerateName: s.GetName() + "-", + Namespace: s.GetNamespace(), + Labels: s.Labels(), + }, + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + Name: "configmap-registry-server", + Image: image, + Command: []string{"configmap-server", "-c", s.Spec.ConfigMap, "-n", s.GetNamespace()}, + Ports: []v1.ContainerPort{ + { + Name: "grpc", + ContainerPort: 50051, + }, + }, + ReadinessProbe: &v1.Probe{ + Handler: v1.Handler{ + Exec: &v1.ExecAction{ + Command: []string{"grpc_health_probe", "-addr=localhost:50051"}, + }, + }, + InitialDelaySeconds: 1, + }, + LivenessProbe: &v1.Probe{ + Handler: v1.Handler{ + Exec: &v1.ExecAction{ + Command: []string{"grpc_health_probe", "-addr=localhost:50051"}, + }, + }, + InitialDelaySeconds: 2, + }, + }, + }, + Tolerations: []v1.Toleration{ + { + Operator: v1.TolerationOpExists, + }, + }, + ServiceAccountName: s.GetName() + "-configmap-server", + }, + } + ownerutil.AddOwner(pod, s.CatalogSource, false, false) + return pod +} + +func (s *configMapCatalogSourceDecorator) ServiceAccount() *v1.ServiceAccount { + sa := &v1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Name: s.serviceAccountName(), + Namespace: s.GetNamespace(), + }, + } + ownerutil.AddOwner(sa, s.CatalogSource, false, false) + return sa +} + +func (s *configMapCatalogSourceDecorator) Role() *rbacv1.Role { + role := &rbacv1.Role{ + ObjectMeta: metav1.ObjectMeta{ + Name: s.roleName(), + Namespace: s.GetNamespace(), + }, + Rules: []rbacv1.PolicyRule{ + { + Verbs: []string{"get"}, + APIGroups: []string{""}, + Resources: []string{"configmaps"}, + ResourceNames: []string{s.Spec.ConfigMap}, + }, + }, + } + ownerutil.AddOwner(role, s.CatalogSource, false, false) + return role +} + +func (s *configMapCatalogSourceDecorator) RoleBinding() *rbacv1.RoleBinding { + rb := &rbacv1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: s.GetName() + "-server-configmap-reader", + Namespace: s.GetNamespace(), + }, + Subjects: []rbacv1.Subject{ + { + Kind: "ServiceAccount", + Name: s.serviceAccountName(), + Namespace: s.GetNamespace(), + }, + }, + RoleRef: rbacv1.RoleRef{ + APIGroup: "rbac.authorization.k8s.io", + Kind: "Role", + Name: s.roleName(), + }, + } + ownerutil.AddOwner(rb, s.CatalogSource, false, false) + return rb +} + +type ConfigMapRegistryReconciler struct { + Lister operatorlister.OperatorLister + OpClient operatorclient.ClientInterface + Image string +} + +var _ RegistryReconciler = &ConfigMapRegistryReconciler{} + +func (c *ConfigMapRegistryReconciler) currentService(source configMapCatalogSourceDecorator) *v1.Service { + serviceName := source.Service().GetName() + service, err := c.Lister.CoreV1().ServiceLister().Services(source.GetNamespace()).Get(serviceName) + if err != nil { + logrus.WithField("service", serviceName).Debug("couldn't find service in cache") + return nil + } + return service +} + +func (c *ConfigMapRegistryReconciler) currentServiceAccount(source configMapCatalogSourceDecorator) *v1.ServiceAccount { + serviceAccountName := source.ServiceAccount().GetName() + serviceAccount, err := c.Lister.CoreV1().ServiceAccountLister().ServiceAccounts(source.GetNamespace()).Get(serviceAccountName) + if err != nil { + logrus.WithField("serviceAccouint", serviceAccountName).WithError(err).Debug("couldn't find service account in cache") + return nil + } + return serviceAccount +} + +func (c *ConfigMapRegistryReconciler) currentRole(source configMapCatalogSourceDecorator) *rbacv1.Role { + roleName := source.Role().GetName() + role, err := c.Lister.RbacV1().RoleLister().Roles(source.GetNamespace()).Get(roleName) + if err != nil { + logrus.WithField("role", roleName).WithError(err).Debug("couldn't find role in cache") + return nil + } + return role +} + +func (c *ConfigMapRegistryReconciler) currentRoleBinding(source configMapCatalogSourceDecorator) *rbacv1.RoleBinding { + roleBindingName := source.RoleBinding().GetName() + roleBinding, err := c.Lister.RbacV1().RoleBindingLister().RoleBindings(source.GetNamespace()).Get(roleBindingName) + if err != nil { + logrus.WithField("roleBinding", roleBindingName).WithError(err).Debug("couldn't find role binding in cache") + return nil + } + return roleBinding +} + +func (c *ConfigMapRegistryReconciler) currentPods(source configMapCatalogSourceDecorator, image string) []*v1.Pod { + podName := source.Pod(image).GetName() + pods, err := c.Lister.CoreV1().PodLister().Pods(source.GetNamespace()).List(labels.SelectorFromSet(source.Selector())) + if err != nil { + logrus.WithField("pod", podName).WithError(err).Debug("couldn't find pod in cache") + return nil + } + if len(pods) > 1 { + logrus.WithField("selector", source.Selector()).Debug("multiple pods found for selector") + } + return pods +} + +func (c *ConfigMapRegistryReconciler) currentPodsWithCorrectResourceVersion(source configMapCatalogSourceDecorator, image string) []*v1.Pod { + podName := source.Pod(image).GetName() + pods, err := c.Lister.CoreV1().PodLister().Pods(source.GetNamespace()).List(labels.SelectorFromValidatedSet(source.Labels())) + if err != nil { + logrus.WithField("pod", podName).WithError(err).Debug("couldn't find pod in cache") + return nil + } + if len(pods) > 1 { + logrus.WithField("selector", source.Labels()).Debug("multiple pods found for selector") + } + return pods +} + +// Ensure that all components of registry server are up to date. +func (c *ConfigMapRegistryReconciler) EnsureRegistryServer(catalogSource *v1alpha1.CatalogSource) error { + source := configMapCatalogSourceDecorator{catalogSource} + + image := c.Image + if source.Spec.SourceType == "grpc" { + image = source.Spec.Image + } + if image == "" { + return fmt.Errorf("no image for registry") + } + + // if service status is nil, we force create every object to ensure they're created the first time + overwrite := source.Status.RegistryServiceStatus == nil + overwritePod := overwrite + + if source.Spec.SourceType == v1alpha1.SourceTypeConfigmap || source.Spec.SourceType == v1alpha1.SourceTypeInternal { + // fetch configmap first, exit early if we can't find it + configMap, err := c.Lister.CoreV1().ConfigMapLister().ConfigMaps(source.GetNamespace()).Get(source.Spec.ConfigMap) + if err != nil { + return fmt.Errorf("unable to get configmap %s/%s from cache", source.GetNamespace(), source.Spec.ConfigMap) + } + + if source.ConfigMapChanges(configMap) { + catalogSource.Status.ConfigMapResource = &v1alpha1.ConfigMapResourceReference{ + Name: configMap.GetName(), + Namespace: configMap.GetNamespace(), + UID: configMap.GetUID(), + ResourceVersion: configMap.GetResourceVersion(), + } + + // recreate the pod if there are configmap changes; this causes the db to be rebuilt + overwritePod = true + } + + // recreate the pod if no existing pod is serving the latest image + if len(c.currentPodsWithCorrectResourceVersion(source, image)) == 0 { + overwritePod = true + } + } + + //TODO: if any of these error out, we should write a status back (possibly set RegistryServiceStatus to nil so they get recreated) + if err := c.ensureServiceAccount(source, overwrite); err != nil { + return errors.Wrapf(err, "error ensuring service account: %s", source.serviceAccountName()) + } + if err := c.ensureRole(source, overwrite); err != nil { + return errors.Wrapf(err, "error ensuring role: %s", source.roleName()) + } + if err := c.ensureRoleBinding(source, overwrite); err != nil { + return errors.Wrapf(err, "error ensuring rolebinding: %s", source.RoleBinding().GetName()) + } + if err := c.ensurePod(source, overwritePod); err != nil { + return errors.Wrapf(err, "error ensuring pod: %s", source.Pod(image).GetName()) + } + if err := c.ensureService(source, overwrite); err != nil { + return errors.Wrapf(err, "error ensuring service: %s", source.Service().GetName()) + } + + if overwritePod { + catalogSource.Status.RegistryServiceStatus = &v1alpha1.RegistryServiceStatus{ + CreatedAt: timeNow(), + Protocol: "grpc", + ServiceName: source.Service().GetName(), + ServiceNamespace: source.GetNamespace(), + Port: fmt.Sprintf("%d", source.Service().Spec.Ports[0].Port), + } + catalogSource.Status.LastSync = timeNow() + } + return nil +} + +func (c *ConfigMapRegistryReconciler) ensureServiceAccount(source configMapCatalogSourceDecorator, overwrite bool) error { + serviceAccount := source.ServiceAccount() + if c.currentServiceAccount(source) != nil { + if !overwrite { + return nil + } + if err := c.OpClient.DeleteServiceAccount(serviceAccount.GetNamespace(), serviceAccount.GetName(), metav1.NewDeleteOptions(0)); err != nil { + return err + } + } + _, err := c.OpClient.CreateServiceAccount(serviceAccount) + return err +} + +func (c *ConfigMapRegistryReconciler) ensureRole(source configMapCatalogSourceDecorator, overwrite bool) error { + role := source.Role() + if c.currentRole(source) != nil { + if !overwrite { + return nil + } + if err := c.OpClient.DeleteRole(role.GetNamespace(), role.GetName(), metav1.NewDeleteOptions(0)); err != nil { + return err + } + } + _, err := c.OpClient.CreateRole(role) + return err +} + +func (c *ConfigMapRegistryReconciler) ensureRoleBinding(source configMapCatalogSourceDecorator, overwrite bool) error { + roleBinding := source.RoleBinding() + if c.currentRoleBinding(source) != nil { + if !overwrite { + return nil + } + if err := c.OpClient.DeleteRoleBinding(roleBinding.GetNamespace(), roleBinding.GetName(), metav1.NewDeleteOptions(0)); err != nil { + return err + } + } + _, err := c.OpClient.CreateRoleBinding(roleBinding) + return err +} + +func (c *ConfigMapRegistryReconciler) ensurePod(source configMapCatalogSourceDecorator, overwrite bool) error { + pod := source.Pod(c.Image) + currentPods := c.currentPods(source, c.Image) + if len(currentPods) > 0 { + if !overwrite { + return nil + } + for _, p := range currentPods { + if err := c.OpClient.KubernetesInterface().CoreV1().Pods(pod.GetNamespace()).Delete(p.GetName(), metav1.NewDeleteOptions(0)); err != nil { + return errors.Wrapf(err, "error deleting old pod: %s", p.GetName()) + } + } + } + _, err := c.OpClient.KubernetesInterface().CoreV1().Pods(pod.GetNamespace()).Create(pod) + if err == nil { + return nil + } + return errors.Wrapf(err, "error creating new pod: %s", pod.GetGenerateName()) +} + +func (c *ConfigMapRegistryReconciler) ensureService(source configMapCatalogSourceDecorator, overwrite bool) error { + service := source.Service() + if c.currentService(source) != nil { + if !overwrite { + return nil + } + if err := c.OpClient.DeleteService(service.GetNamespace(), service.GetName(), metav1.NewDeleteOptions(0)); err != nil { + return err + } + } + _, err := c.OpClient.CreateService(service) + return err +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/reconciler/grpc.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/reconciler/grpc.go new file mode 100644 index 0000000000..fec50d4a22 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/reconciler/grpc.go @@ -0,0 +1,208 @@ +package reconciler + +import ( + "fmt" + + "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient" + "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister" + "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" + "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/util/intstr" +) + +// grpcCatalogSourceDecorator wraps CatalogSource to add additional methods +type grpcCatalogSourceDecorator struct { + *v1alpha1.CatalogSource +} + +func (s *grpcCatalogSourceDecorator) Selector() labels.Selector { + return labels.SelectorFromValidatedSet(map[string]string{ + "olm.catalogSource": s.GetName(), + }) +} + +func (s *grpcCatalogSourceDecorator) Labels() map[string]string { + return map[string]string{ + "olm.catalogSource": s.GetName(), + } +} + +func (s *grpcCatalogSourceDecorator) Service() *v1.Service { + svc := &v1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: s.GetName(), + Namespace: s.GetNamespace(), + }, + Spec: v1.ServiceSpec{ + Ports: []v1.ServicePort{ + { + Name: "grpc", + Port: 50051, + TargetPort: intstr.FromInt(50051), + }, + }, + Selector: s.Labels(), + }, + } + ownerutil.AddOwner(svc, s.CatalogSource, false, false) + return svc +} + +func (s *grpcCatalogSourceDecorator) Pod() *v1.Pod { + pod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + GenerateName: s.GetName() + "-", + Namespace: s.GetNamespace(), + Labels: s.Labels(), + }, + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + Name: "registry-server", + Image: s.Spec.Image, + Ports: []v1.ContainerPort{ + { + Name: "grpc", + ContainerPort: 50051, + }, + }, + ReadinessProbe: &v1.Probe{ + Handler: v1.Handler{ + Exec: &v1.ExecAction{ + Command: []string{"grpc_health_probe", "-addr=localhost:50051"}, + }, + }, + InitialDelaySeconds: 5, + }, + LivenessProbe: &v1.Probe{ + Handler: v1.Handler{ + Exec: &v1.ExecAction{ + Command: []string{"grpc_health_probe", "-addr=localhost:50051"}, + }, + }, + InitialDelaySeconds: 10, + }, + }, + }, + Tolerations: []v1.Toleration{ + { + Operator: v1.TolerationOpExists, + }, + }, + }, + } + ownerutil.AddOwner(pod, s.CatalogSource, false, false) + return pod +} + +type GrpcRegistryReconciler struct { + Lister operatorlister.OperatorLister + OpClient operatorclient.ClientInterface +} + +var _ RegistryReconciler = &GrpcRegistryReconciler{} + +func (c *GrpcRegistryReconciler) currentService(source grpcCatalogSourceDecorator) *v1.Service { + serviceName := source.Service().GetName() + service, err := c.Lister.CoreV1().ServiceLister().Services(source.GetNamespace()).Get(serviceName) + if err != nil { + logrus.WithField("service", serviceName).Warn("couldn't find service in cache") + return nil + } + return service +} + +func (c *GrpcRegistryReconciler) currentPods(source grpcCatalogSourceDecorator) []*v1.Pod { + pods, err := c.Lister.CoreV1().PodLister().Pods(source.GetNamespace()).List(source.Selector()) + if err != nil { + logrus.WithError(err).Warn("couldn't find pod in cache") + return nil + } + if len(pods) > 1 { + logrus.WithField("selector", source.Selector()).Warn("multiple pods found for selector") + } + return pods +} + +func (c *GrpcRegistryReconciler) currentPodsWithCorrectImage(source grpcCatalogSourceDecorator) []*v1.Pod { + pods, err := c.Lister.CoreV1().PodLister().Pods(source.GetNamespace()).List(labels.SelectorFromValidatedSet(source.Labels())) + if err != nil { + logrus.WithError(err).Warn("couldn't find pod in cache") + return nil + } + found := []*v1.Pod{} + for _, p := range pods { + if p.Spec.Containers[0].Image == source.Spec.Image { + found = append(found, p) + } + } + return found +} + +// Ensure that all components of registry server are up to date. +func (c *GrpcRegistryReconciler) EnsureRegistryServer(catalogSource *v1alpha1.CatalogSource) error { + source := grpcCatalogSourceDecorator{catalogSource} + + // if service status is nil, we force create every object to ensure they're created the first time + overwrite := source.Status.RegistryServiceStatus == nil + // recreate the pod if no existing pod is serving the latest image + overwritePod := overwrite || len(c.currentPodsWithCorrectImage(source)) == 0 + + //TODO: if any of these error out, we should write a status back (possibly set RegistryServiceStatus to nil so they get recreated) + if err := c.ensurePod(source, overwritePod); err != nil { + return errors.Wrapf(err, "error ensuring pod: %s", source.Pod().GetName()) + } + if err := c.ensureService(source, overwrite); err != nil { + return errors.Wrapf(err, "error ensuring service: %s", source.Service().GetName()) + } + + if overwritePod { + catalogSource.Status.RegistryServiceStatus = &v1alpha1.RegistryServiceStatus{ + CreatedAt: timeNow(), + Protocol: "grpc", + ServiceName: source.Service().GetName(), + ServiceNamespace: source.GetNamespace(), + Port: fmt.Sprintf("%d", source.Service().Spec.Ports[0].Port), + } + catalogSource.Status.LastSync = timeNow() + } + return nil +} + +func (c *GrpcRegistryReconciler) ensurePod(source grpcCatalogSourceDecorator, overwrite bool) error { + currentPods := c.currentPods(source) + if len(currentPods) > 0 { + if !overwrite { + return nil + } + for _, p := range currentPods { + if err := c.OpClient.KubernetesInterface().CoreV1().Pods(source.GetNamespace()).Delete(p.GetName(), metav1.NewDeleteOptions(0)); err != nil { + return errors.Wrapf(err, "error deleting old pod: %s", p.GetName()) + } + } + } + _, err := c.OpClient.KubernetesInterface().CoreV1().Pods(source.GetNamespace()).Create(source.Pod()) + if err == nil { + return nil + } + return errors.Wrapf(err, "error creating new pod: %s", source.Pod().GetGenerateName()) +} + +func (c *GrpcRegistryReconciler) ensureService(source grpcCatalogSourceDecorator, overwrite bool) error { + service := source.Service() + if c.currentService(source) != nil { + if !overwrite { + return nil + } + if err := c.OpClient.DeleteService(service.GetNamespace(), service.GetName(), metav1.NewDeleteOptions(0)); err != nil { + return err + } + } + _, err := c.OpClient.CreateService(service) + return err +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/reconciler/grpc_address.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/reconciler/grpc_address.go new file mode 100644 index 0000000000..88548769c9 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/reconciler/grpc_address.go @@ -0,0 +1,19 @@ +package reconciler + +import ( + "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" +) + +type GrpcAddressRegistryReconciler struct{} + +var _ RegistryReconciler = &GrpcAddressRegistryReconciler{} + +func (g *GrpcAddressRegistryReconciler) EnsureRegistryServer(catalogSource *v1alpha1.CatalogSource) error { + + catalogSource.Status.RegistryServiceStatus = &v1alpha1.RegistryServiceStatus{ + CreatedAt: timeNow(), + Protocol: "grpc", + } + + return nil +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/reconciler/reconciler.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/reconciler/reconciler.go new file mode 100644 index 0000000000..0808e0711f --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/reconciler/reconciler.go @@ -0,0 +1,43 @@ +//go:generate counterfeiter -o ../../../fakes/fake_reconciler_reconciler.go . ReconcilerFactory +package reconciler + +import ( + "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient" + "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister" +) + +type RegistryReconciler interface { + EnsureRegistryServer(catalogSource *v1alpha1.CatalogSource) error +} + +type ReconcilerFactory interface { + ReconcilerForSource(source *v1alpha1.CatalogSource) RegistryReconciler +} + +type RegistryReconcilerFactory struct { + Lister operatorlister.OperatorLister + OpClient operatorclient.ClientInterface + ConfigMapServerImage string +} + +func (r *RegistryReconcilerFactory) ReconcilerForSource(source *v1alpha1.CatalogSource) RegistryReconciler { + switch source.Spec.SourceType { + case v1alpha1.SourceTypeInternal, v1alpha1.SourceTypeConfigmap: + return &ConfigMapRegistryReconciler{ + Lister: r.Lister, + OpClient: r.OpClient, + Image: r.ConfigMapServerImage, + } + case v1alpha1.SourceTypeGrpc: + if source.Spec.Image != "" { + return &GrpcRegistryReconciler{ + Lister: r.Lister, + OpClient: r.OpClient, + } + } else if source.Spec.Address != "" { + return &GrpcAddressRegistryReconciler{} + } + } + return nil +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/evolver.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/evolver.go new file mode 100644 index 0000000000..5eb9ef9632 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/evolver.go @@ -0,0 +1,140 @@ +package resolver + +import ( + opregistry "github.com/operator-framework/operator-registry/pkg/registry" + "github.com/pkg/errors" +) + +// TODO: this should take a cancellable context for killing long resolution +// TODO: return a set of errors or warnings of unusual states to know about (we expect evolve to always succeed, because it can be a no-op) + +// Evolvers modify a generation to a new state +type Evolver interface { + Evolve(add map[OperatorSourceInfo]struct{}) error +} + +type NamespaceGenerationEvolver struct { + querier SourceQuerier + gen Generation +} + +func NewNamespaceGenerationEvolver(querier SourceQuerier, gen Generation) Evolver { + return &NamespaceGenerationEvolver{querier: querier, gen: gen} +} + +// Evolve takes new requested operators, adds them to the generation, and attempts to resolve dependencies with querier +func (e *NamespaceGenerationEvolver) Evolve(add map[OperatorSourceInfo]struct{}) error { + if err := e.querier.Queryable(); err != nil { + return err + } + + // check for updates to existing operators + if err := e.checkForUpdates(); err != nil { + return err + } + + // fetch bundles for new operators (aren't yet tracked) + if err := e.addNewOperators(add); err != nil { + return err + } + + // attempt to resolve any missing apis as a result expanding the generation of operators + if err := e.queryForRequiredAPIs(); err != nil { + return err + } + + // for any remaining missing APIs, attempt to downgrade the operator that required them + // this may contract the generation back to the original set! + e.downgradeAPIs() + return nil +} + +func (e *NamespaceGenerationEvolver) checkForUpdates() error { + // take a snapshot of the current generation so that we don't update the same operator twice in one resolution + for _, op := range e.gen.Operators().Snapshot() { + // only check for updates if we have sourceinfo + if op.SourceInfo() == &ExistingOperator { + continue + } + + bundle, key, err := e.querier.FindReplacement(op.Identifier(), op.SourceInfo().Package, op.SourceInfo().Channel, op.SourceInfo().Catalog) + if err != nil || bundle == nil { + continue + } + + o, err := NewOperatorFromBundle(bundle, op.SourceInfo().StartingCSV, *key) + if err != nil { + return errors.Wrap(err, "error parsing bundle") + } + if err := e.gen.AddOperator(o); err != nil { + if err != nil { + return errors.Wrap(err, "error calculating generation changes due to new bundle") + } + } + e.gen.RemoveOperator(op) + } + return nil +} + +func (e *NamespaceGenerationEvolver) addNewOperators(add map[OperatorSourceInfo]struct{}) error { + for s := range add { + var bundle *opregistry.Bundle + var key *CatalogKey + var err error + if s.StartingCSV != "" { + bundle, key, err = e.querier.FindBundle(s.Package, s.Channel, s.StartingCSV, s.Catalog) + } else { + bundle, key, err = e.querier.FindLatestBundle(s.Package, s.Channel, s.Catalog) + } + if err != nil { + // TODO: log or collect warnings + return errors.Wrapf(err, "%s not found", s) + } + + o, err := NewOperatorFromBundle(bundle, s.StartingCSV, *key) + if err != nil { + return errors.Wrap(err, "error parsing bundle") + } + if err := e.gen.AddOperator(o); err != nil { + if err != nil { + return errors.Wrap(err, "error calculating generation changes due to new bundle") + } + } + } + return nil +} + +func (e *NamespaceGenerationEvolver) queryForRequiredAPIs() error { + e.gen.ResetUnchecked() + + for { + api := e.gen.UncheckedAPIs().PopAPIKey() + if api == nil { + break + } + e.gen.MarkAPIChecked(*api) + + // attempt to find a bundle that provides that api + if bundle, key, err := e.querier.FindProvider(*api); err == nil { + // add a bundle that provides the api to the generation + o, err := NewOperatorFromBundle(bundle, "", *key) + if err != nil { + return errors.Wrap(err, "error parsing bundle") + } + if err := e.gen.AddOperator(o); err != nil { + return errors.Wrap(err, "error calculating generation changes due to new bundle") + } + } + } + return nil +} + +func (e *NamespaceGenerationEvolver) downgradeAPIs() { + e.gen.ResetUnchecked() + for missingAPIs := e.gen.MissingAPIs(); len(missingAPIs) > 0; { + requirers := missingAPIs.PopAPIRequirers() + for _, op := range requirers { + e.gen.RemoveOperator(op) + } + } +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/fakes/fake_registry_client.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/fakes/fake_registry_client.go new file mode 100644 index 0000000000..44ad49eec0 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/fakes/fake_registry_client.go @@ -0,0 +1,373 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package fakes + +import ( + context "context" + sync "sync" + + client "github.com/operator-framework/operator-registry/pkg/client" + registry "github.com/operator-framework/operator-registry/pkg/registry" +) + +type FakeInterface struct { + GetBundleStub func(context.Context, string, string, string) (*registry.Bundle, error) + getBundleMutex sync.RWMutex + getBundleArgsForCall []struct { + arg1 context.Context + arg2 string + arg3 string + arg4 string + } + getBundleReturns struct { + result1 *registry.Bundle + result2 error + } + getBundleReturnsOnCall map[int]struct { + result1 *registry.Bundle + result2 error + } + GetBundleInPackageChannelStub func(context.Context, string, string) (*registry.Bundle, error) + getBundleInPackageChannelMutex sync.RWMutex + getBundleInPackageChannelArgsForCall []struct { + arg1 context.Context + arg2 string + arg3 string + } + getBundleInPackageChannelReturns struct { + result1 *registry.Bundle + result2 error + } + getBundleInPackageChannelReturnsOnCall map[int]struct { + result1 *registry.Bundle + result2 error + } + GetBundleThatProvidesStub func(context.Context, string, string, string) (*registry.Bundle, error) + getBundleThatProvidesMutex sync.RWMutex + getBundleThatProvidesArgsForCall []struct { + arg1 context.Context + arg2 string + arg3 string + arg4 string + } + getBundleThatProvidesReturns struct { + result1 *registry.Bundle + result2 error + } + getBundleThatProvidesReturnsOnCall map[int]struct { + result1 *registry.Bundle + result2 error + } + GetReplacementBundleInPackageChannelStub func(context.Context, string, string, string) (*registry.Bundle, error) + getReplacementBundleInPackageChannelMutex sync.RWMutex + getReplacementBundleInPackageChannelArgsForCall []struct { + arg1 context.Context + arg2 string + arg3 string + arg4 string + } + getReplacementBundleInPackageChannelReturns struct { + result1 *registry.Bundle + result2 error + } + getReplacementBundleInPackageChannelReturnsOnCall map[int]struct { + result1 *registry.Bundle + result2 error + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *FakeInterface) GetBundle(arg1 context.Context, arg2 string, arg3 string, arg4 string) (*registry.Bundle, error) { + fake.getBundleMutex.Lock() + ret, specificReturn := fake.getBundleReturnsOnCall[len(fake.getBundleArgsForCall)] + fake.getBundleArgsForCall = append(fake.getBundleArgsForCall, struct { + arg1 context.Context + arg2 string + arg3 string + arg4 string + }{arg1, arg2, arg3, arg4}) + fake.recordInvocation("GetBundle", []interface{}{arg1, arg2, arg3, arg4}) + fake.getBundleMutex.Unlock() + if fake.GetBundleStub != nil { + return fake.GetBundleStub(arg1, arg2, arg3, arg4) + } + if specificReturn { + return ret.result1, ret.result2 + } + fakeReturns := fake.getBundleReturns + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *FakeInterface) GetBundleCallCount() int { + fake.getBundleMutex.RLock() + defer fake.getBundleMutex.RUnlock() + return len(fake.getBundleArgsForCall) +} + +func (fake *FakeInterface) GetBundleCalls(stub func(context.Context, string, string, string) (*registry.Bundle, error)) { + fake.getBundleMutex.Lock() + defer fake.getBundleMutex.Unlock() + fake.GetBundleStub = stub +} + +func (fake *FakeInterface) GetBundleArgsForCall(i int) (context.Context, string, string, string) { + fake.getBundleMutex.RLock() + defer fake.getBundleMutex.RUnlock() + argsForCall := fake.getBundleArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4 +} + +func (fake *FakeInterface) GetBundleReturns(result1 *registry.Bundle, result2 error) { + fake.getBundleMutex.Lock() + defer fake.getBundleMutex.Unlock() + fake.GetBundleStub = nil + fake.getBundleReturns = struct { + result1 *registry.Bundle + result2 error + }{result1, result2} +} + +func (fake *FakeInterface) GetBundleReturnsOnCall(i int, result1 *registry.Bundle, result2 error) { + fake.getBundleMutex.Lock() + defer fake.getBundleMutex.Unlock() + fake.GetBundleStub = nil + if fake.getBundleReturnsOnCall == nil { + fake.getBundleReturnsOnCall = make(map[int]struct { + result1 *registry.Bundle + result2 error + }) + } + fake.getBundleReturnsOnCall[i] = struct { + result1 *registry.Bundle + result2 error + }{result1, result2} +} + +func (fake *FakeInterface) GetBundleInPackageChannel(arg1 context.Context, arg2 string, arg3 string) (*registry.Bundle, error) { + fake.getBundleInPackageChannelMutex.Lock() + ret, specificReturn := fake.getBundleInPackageChannelReturnsOnCall[len(fake.getBundleInPackageChannelArgsForCall)] + fake.getBundleInPackageChannelArgsForCall = append(fake.getBundleInPackageChannelArgsForCall, struct { + arg1 context.Context + arg2 string + arg3 string + }{arg1, arg2, arg3}) + fake.recordInvocation("GetBundleInPackageChannel", []interface{}{arg1, arg2, arg3}) + fake.getBundleInPackageChannelMutex.Unlock() + if fake.GetBundleInPackageChannelStub != nil { + return fake.GetBundleInPackageChannelStub(arg1, arg2, arg3) + } + if specificReturn { + return ret.result1, ret.result2 + } + fakeReturns := fake.getBundleInPackageChannelReturns + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *FakeInterface) GetBundleInPackageChannelCallCount() int { + fake.getBundleInPackageChannelMutex.RLock() + defer fake.getBundleInPackageChannelMutex.RUnlock() + return len(fake.getBundleInPackageChannelArgsForCall) +} + +func (fake *FakeInterface) GetBundleInPackageChannelCalls(stub func(context.Context, string, string) (*registry.Bundle, error)) { + fake.getBundleInPackageChannelMutex.Lock() + defer fake.getBundleInPackageChannelMutex.Unlock() + fake.GetBundleInPackageChannelStub = stub +} + +func (fake *FakeInterface) GetBundleInPackageChannelArgsForCall(i int) (context.Context, string, string) { + fake.getBundleInPackageChannelMutex.RLock() + defer fake.getBundleInPackageChannelMutex.RUnlock() + argsForCall := fake.getBundleInPackageChannelArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3 +} + +func (fake *FakeInterface) GetBundleInPackageChannelReturns(result1 *registry.Bundle, result2 error) { + fake.getBundleInPackageChannelMutex.Lock() + defer fake.getBundleInPackageChannelMutex.Unlock() + fake.GetBundleInPackageChannelStub = nil + fake.getBundleInPackageChannelReturns = struct { + result1 *registry.Bundle + result2 error + }{result1, result2} +} + +func (fake *FakeInterface) GetBundleInPackageChannelReturnsOnCall(i int, result1 *registry.Bundle, result2 error) { + fake.getBundleInPackageChannelMutex.Lock() + defer fake.getBundleInPackageChannelMutex.Unlock() + fake.GetBundleInPackageChannelStub = nil + if fake.getBundleInPackageChannelReturnsOnCall == nil { + fake.getBundleInPackageChannelReturnsOnCall = make(map[int]struct { + result1 *registry.Bundle + result2 error + }) + } + fake.getBundleInPackageChannelReturnsOnCall[i] = struct { + result1 *registry.Bundle + result2 error + }{result1, result2} +} + +func (fake *FakeInterface) GetBundleThatProvides(arg1 context.Context, arg2 string, arg3 string, arg4 string) (*registry.Bundle, error) { + fake.getBundleThatProvidesMutex.Lock() + ret, specificReturn := fake.getBundleThatProvidesReturnsOnCall[len(fake.getBundleThatProvidesArgsForCall)] + fake.getBundleThatProvidesArgsForCall = append(fake.getBundleThatProvidesArgsForCall, struct { + arg1 context.Context + arg2 string + arg3 string + arg4 string + }{arg1, arg2, arg3, arg4}) + fake.recordInvocation("GetBundleThatProvides", []interface{}{arg1, arg2, arg3, arg4}) + fake.getBundleThatProvidesMutex.Unlock() + if fake.GetBundleThatProvidesStub != nil { + return fake.GetBundleThatProvidesStub(arg1, arg2, arg3, arg4) + } + if specificReturn { + return ret.result1, ret.result2 + } + fakeReturns := fake.getBundleThatProvidesReturns + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *FakeInterface) GetBundleThatProvidesCallCount() int { + fake.getBundleThatProvidesMutex.RLock() + defer fake.getBundleThatProvidesMutex.RUnlock() + return len(fake.getBundleThatProvidesArgsForCall) +} + +func (fake *FakeInterface) GetBundleThatProvidesCalls(stub func(context.Context, string, string, string) (*registry.Bundle, error)) { + fake.getBundleThatProvidesMutex.Lock() + defer fake.getBundleThatProvidesMutex.Unlock() + fake.GetBundleThatProvidesStub = stub +} + +func (fake *FakeInterface) GetBundleThatProvidesArgsForCall(i int) (context.Context, string, string, string) { + fake.getBundleThatProvidesMutex.RLock() + defer fake.getBundleThatProvidesMutex.RUnlock() + argsForCall := fake.getBundleThatProvidesArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4 +} + +func (fake *FakeInterface) GetBundleThatProvidesReturns(result1 *registry.Bundle, result2 error) { + fake.getBundleThatProvidesMutex.Lock() + defer fake.getBundleThatProvidesMutex.Unlock() + fake.GetBundleThatProvidesStub = nil + fake.getBundleThatProvidesReturns = struct { + result1 *registry.Bundle + result2 error + }{result1, result2} +} + +func (fake *FakeInterface) GetBundleThatProvidesReturnsOnCall(i int, result1 *registry.Bundle, result2 error) { + fake.getBundleThatProvidesMutex.Lock() + defer fake.getBundleThatProvidesMutex.Unlock() + fake.GetBundleThatProvidesStub = nil + if fake.getBundleThatProvidesReturnsOnCall == nil { + fake.getBundleThatProvidesReturnsOnCall = make(map[int]struct { + result1 *registry.Bundle + result2 error + }) + } + fake.getBundleThatProvidesReturnsOnCall[i] = struct { + result1 *registry.Bundle + result2 error + }{result1, result2} +} + +func (fake *FakeInterface) GetReplacementBundleInPackageChannel(arg1 context.Context, arg2 string, arg3 string, arg4 string) (*registry.Bundle, error) { + fake.getReplacementBundleInPackageChannelMutex.Lock() + ret, specificReturn := fake.getReplacementBundleInPackageChannelReturnsOnCall[len(fake.getReplacementBundleInPackageChannelArgsForCall)] + fake.getReplacementBundleInPackageChannelArgsForCall = append(fake.getReplacementBundleInPackageChannelArgsForCall, struct { + arg1 context.Context + arg2 string + arg3 string + arg4 string + }{arg1, arg2, arg3, arg4}) + fake.recordInvocation("GetReplacementBundleInPackageChannel", []interface{}{arg1, arg2, arg3, arg4}) + fake.getReplacementBundleInPackageChannelMutex.Unlock() + if fake.GetReplacementBundleInPackageChannelStub != nil { + return fake.GetReplacementBundleInPackageChannelStub(arg1, arg2, arg3, arg4) + } + if specificReturn { + return ret.result1, ret.result2 + } + fakeReturns := fake.getReplacementBundleInPackageChannelReturns + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *FakeInterface) GetReplacementBundleInPackageChannelCallCount() int { + fake.getReplacementBundleInPackageChannelMutex.RLock() + defer fake.getReplacementBundleInPackageChannelMutex.RUnlock() + return len(fake.getReplacementBundleInPackageChannelArgsForCall) +} + +func (fake *FakeInterface) GetReplacementBundleInPackageChannelCalls(stub func(context.Context, string, string, string) (*registry.Bundle, error)) { + fake.getReplacementBundleInPackageChannelMutex.Lock() + defer fake.getReplacementBundleInPackageChannelMutex.Unlock() + fake.GetReplacementBundleInPackageChannelStub = stub +} + +func (fake *FakeInterface) GetReplacementBundleInPackageChannelArgsForCall(i int) (context.Context, string, string, string) { + fake.getReplacementBundleInPackageChannelMutex.RLock() + defer fake.getReplacementBundleInPackageChannelMutex.RUnlock() + argsForCall := fake.getReplacementBundleInPackageChannelArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4 +} + +func (fake *FakeInterface) GetReplacementBundleInPackageChannelReturns(result1 *registry.Bundle, result2 error) { + fake.getReplacementBundleInPackageChannelMutex.Lock() + defer fake.getReplacementBundleInPackageChannelMutex.Unlock() + fake.GetReplacementBundleInPackageChannelStub = nil + fake.getReplacementBundleInPackageChannelReturns = struct { + result1 *registry.Bundle + result2 error + }{result1, result2} +} + +func (fake *FakeInterface) GetReplacementBundleInPackageChannelReturnsOnCall(i int, result1 *registry.Bundle, result2 error) { + fake.getReplacementBundleInPackageChannelMutex.Lock() + defer fake.getReplacementBundleInPackageChannelMutex.Unlock() + fake.GetReplacementBundleInPackageChannelStub = nil + if fake.getReplacementBundleInPackageChannelReturnsOnCall == nil { + fake.getReplacementBundleInPackageChannelReturnsOnCall = make(map[int]struct { + result1 *registry.Bundle + result2 error + }) + } + fake.getReplacementBundleInPackageChannelReturnsOnCall[i] = struct { + result1 *registry.Bundle + result2 error + }{result1, result2} +} + +func (fake *FakeInterface) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.getBundleMutex.RLock() + defer fake.getBundleMutex.RUnlock() + fake.getBundleInPackageChannelMutex.RLock() + defer fake.getBundleInPackageChannelMutex.RUnlock() + fake.getBundleThatProvidesMutex.RLock() + defer fake.getBundleThatProvidesMutex.RUnlock() + fake.getReplacementBundleInPackageChannelMutex.RLock() + defer fake.getReplacementBundleInPackageChannelMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *FakeInterface) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} + +var _ client.Interface = new(FakeInterface) diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/generation.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/generation.go new file mode 100644 index 0000000000..97d8ad2eac --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/generation.go @@ -0,0 +1,150 @@ +//go:generate counterfeiter -o fakes/fake_generation.go . SourceQuerier +package resolver + +import ( + "fmt" + + "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + "github.com/operator-framework/operator-registry/pkg/registry" +) + +// Generation represents a set of operators and their required/provided API surfaces at a point in time. +type Generation interface { + AddOperator(o OperatorSurface) error + RemoveOperator(o OperatorSurface) + ResetUnchecked() + MissingAPIs() APIMultiOwnerSet + Operators() OperatorSet + MarkAPIChecked(key registry.APIKey) + UncheckedAPIs() APISet +} + +// NamespaceGeneration represents a generation of operators in a single namespace with methods for managing api checks +type NamespaceGeneration struct { + providedAPIs APIOwnerSet // only allow one provider of any api + requiredAPIs APIMultiOwnerSet // multiple operators may require the same api + uncheckedAPIs APISet // required apis that haven't been checked yet + missingAPIs APIMultiOwnerSet + operators OperatorSet +} + +func NewEmptyGeneration() *NamespaceGeneration { + return &NamespaceGeneration{ + providedAPIs: EmptyAPIOwnerSet(), + requiredAPIs: EmptyAPIMultiOwnerSet(), + uncheckedAPIs: EmptyAPISet(), + missingAPIs: EmptyAPIMultiOwnerSet(), + operators: EmptyOperatorSet(), + } +} + +func NewGenerationFromCluster(csvs []*v1alpha1.ClusterServiceVersion, subs []*v1alpha1.Subscription) (*NamespaceGeneration, error) { + g := NewEmptyGeneration() + + subMap := map[string]*v1alpha1.Subscription{} + for _, s := range subs { + if s.Status.CurrentCSV != "" { + subMap[s.Status.CurrentCSV] = s.DeepCopy() + } + } + for _, csv := range csvs { + op, err := NewOperatorFromCSV(csv) + if err != nil { + return nil, err + } + // If there's a subscription for this CSV, we add the sourceinfo for the subscription + if sub, ok := subMap[op.Identifier()]; ok { + // No need to enable starting csv search since a csv already exists. + op.sourceInfo = &OperatorSourceInfo{ + Package: sub.Spec.Package, + Channel: sub.Spec.Channel, + Catalog: CatalogKey{Name: sub.Spec.CatalogSource, Namespace: sub.Spec.CatalogSourceNamespace}, + } + } + if err := g.AddOperator(op); err != nil { + return nil, err + } + } + return g, nil +} + +func (g *NamespaceGeneration) AddOperator(o OperatorSurface) error { + // add provided apis, error if two owners (that isn't a replacement) + for api := range o.ProvidedAPIs() { + if provider, ok := g.providedAPIs[api]; ok && provider.Identifier() != o.Identifier() && o.Replaces() != provider.Identifier() { + return fmt.Errorf("%v already provided by %s", api, provider.Identifier()) + } + g.providedAPIs[api] = o + + // mark any missing apis that are now provided + delete(g.missingAPIs, api) + delete(g.uncheckedAPIs, api) + } + + // add all requirers of apis + for api := range o.RequiredAPIs() { + if _, ok := g.requiredAPIs[api]; !ok { + g.requiredAPIs[api] = EmptyOperatorSet() + } + g.requiredAPIs[api][o.Identifier()] = o + } + for api := range o.RequiredAPIs() { + if _, ok := g.providedAPIs[api]; !ok { + if _, ok := g.missingAPIs[api]; !ok { + g.missingAPIs[api] = EmptyOperatorSet() + } + // mark new requirements as missing and unchecked + g.missingAPIs[api][o.Identifier()] = o + g.uncheckedAPIs[api] = struct{}{} + } else { + // required api already satisfied + delete(g.missingAPIs, api) + delete(g.uncheckedAPIs, api) + } + } + g.operators[o.Identifier()] = o + return nil +} + +func (g *NamespaceGeneration) RemoveOperator(o OperatorSurface) { + for api := range o.ProvidedAPIs() { + delete(g.providedAPIs, api) + + // if the operator provided apis that others were depending on, mark them as missing + if requirers, ok := g.requiredAPIs[api]; ok && len(requirers) > 0 { + g.missingAPIs[api] = requirers + } + } + for api := range o.RequiredAPIs() { + delete(g.requiredAPIs[api], o.Identifier()) + if len(g.requiredAPIs[api]) == 0 { + delete(g.requiredAPIs, api) + delete(g.missingAPIs, api) + delete(g.uncheckedAPIs, api) + } + } + delete(g.operators, o.Identifier()) +} + +func (g *NamespaceGeneration) MarkAPIChecked(key registry.APIKey) { + delete(g.uncheckedAPIs, key) +} + +func (g *NamespaceGeneration) ResetUnchecked() { + g.uncheckedAPIs = EmptyAPISet() + for api := range g.missingAPIs { + g.uncheckedAPIs[api] = struct{}{} + } +} + +func (g *NamespaceGeneration) MissingAPIs() APIMultiOwnerSet { + return g.missingAPIs +} + +func (g *NamespaceGeneration) UncheckedAPIs() APISet { + return g.uncheckedAPIs +} + +func (g *NamespaceGeneration) Operators() OperatorSet { + return g.operators +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/groups.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/groups.go new file mode 100644 index 0000000000..53c4020f98 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/groups.go @@ -0,0 +1,209 @@ +//go:generate counterfeiter -o ../../../fakes/fake_api_intersection_reconciler.go . APIIntersectionReconciler +package resolver + +import ( + "strings" + + v1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1" +) + +type NamespaceSet map[string]struct{} + +func NewNamespaceSet(namespaces []string) NamespaceSet { + set := make(NamespaceSet) + for _, namespace := range namespaces { + set[namespace] = struct{}{} + } + + return set +} + +// NewNamespaceSetFromString creates a namespace set from a comma-delimited list of namespaces +func NewNamespaceSetFromString(namespaces string) NamespaceSet { + return NewNamespaceSet(strings.Split(namespaces, ",")) +} + +func (n NamespaceSet) Peek() string { + for namespace := range n { + return namespace + } + + return "" +} + +func (n NamespaceSet) Intersection(set NamespaceSet) NamespaceSet { + intersection := make(NamespaceSet) + // Handle special NamespaceAll cases + if n.IsAllNamespaces() { + for namespace := range set { + intersection[namespace] = struct{}{} + } + return intersection + } + if set.IsAllNamespaces() { + for namespace := range n { + intersection[namespace] = struct{}{} + } + return intersection + } + + for namespace := range n { + if _, ok := set[namespace]; ok { + intersection[namespace] = struct{}{} + } + } + + return intersection +} + +func (n NamespaceSet) Union(set NamespaceSet) NamespaceSet { + // Handle special NamespaceAll cases + if n.IsAllNamespaces() { + return n + } + if set.IsAllNamespaces() { + return set + } + union := make(NamespaceSet) + for namespace := range n { + union[namespace] = struct{}{} + } + for namespace := range set { + union[namespace] = struct{}{} + } + return union +} + +func (n NamespaceSet) Contains(namespace string) bool { + if n.IsAllNamespaces() { + return true + } + _, ok := n[namespace] + return ok +} + +func (n NamespaceSet) IsAllNamespaces() bool { + if len(n) == 1 && n.Peek() == "" { + return true + } + return false +} + +type OperatorGroupSurface interface { + Identifier() string + Namespace() string + Targets() NamespaceSet + ProvidedAPIs() APISet + GroupIntersection(groups ...OperatorGroupSurface) []OperatorGroupSurface +} + +var _ OperatorGroupSurface = &OperatorGroup{} + +type OperatorGroup struct { + namespace string + name string + targets NamespaceSet + providedAPIs APISet +} + +func NewOperatorGroup(group *v1.OperatorGroup) *OperatorGroup { + // Add operatorgroup namespace if not NamespaceAll + namespaces := group.Status.Namespaces + if len(namespaces) >= 1 && namespaces[0] != "" { + namespaces = append(namespaces, group.GetNamespace()) + } + // TODO: Sanitize OperatorGroup if len(namespaces) > 1 and contains "" + gvksStr := group.GetAnnotations()[v1.OperatorGroupProvidedAPIsAnnotationKey] + + return &OperatorGroup{ + namespace: group.GetNamespace(), + name: group.GetName(), + targets: NewNamespaceSet(namespaces), + providedAPIs: GVKStringToProvidedAPISet(gvksStr), + } +} + +func NewOperatorGroupSurfaces(groups ...v1.OperatorGroup) []OperatorGroupSurface { + operatorGroups := make([]OperatorGroupSurface, len(groups)) + for i, group := range groups { + operatorGroups[i] = NewOperatorGroup(&group) + } + + return operatorGroups +} + +func (g *OperatorGroup) Identifier() string { + return g.name + "/" + g.namespace +} + +func (g *OperatorGroup) Namespace() string { + return g.namespace +} + +func (g *OperatorGroup) Targets() NamespaceSet { + return g.targets +} + +func (g *OperatorGroup) ProvidedAPIs() APISet { + return g.providedAPIs +} + +func (g *OperatorGroup) GroupIntersection(groups ...OperatorGroupSurface) []OperatorGroupSurface { + intersection := []OperatorGroupSurface{} + for _, group := range groups { + if group.Identifier() == g.Identifier() { + // Skip self if present + continue + } + if len(g.targets.Intersection(group.Targets())) > 0 { + // TODO: This uses tons of space - maps are copied every time + intersection = append(intersection, group) + } + } + + return intersection +} + +type APIReconciliationResult int + +const ( + RemoveAPIs APIReconciliationResult = iota + AddAPIs + APIConflict + NoAPIConflict +) + +type APIIntersectionReconciler interface { + Reconcile(add APISet, group OperatorGroupSurface, otherGroups ...OperatorGroupSurface) APIReconciliationResult +} + +type APIIntersectionReconcileFunc func(add APISet, group OperatorGroupSurface, otherGroups ...OperatorGroupSurface) APIReconciliationResult + +func (a APIIntersectionReconcileFunc) Reconcile(add APISet, group OperatorGroupSurface, otherGroups ...OperatorGroupSurface) APIReconciliationResult { + return a(add, group, otherGroups...) +} + +func ReconcileAPIIntersection(add APISet, group OperatorGroupSurface, otherGroups ...OperatorGroupSurface) APIReconciliationResult { + groupIntersection := group.GroupIntersection(otherGroups...) + providedAPIIntersection := make(APISet) + for _, g := range groupIntersection { + providedAPIIntersection = providedAPIIntersection.Union(g.ProvidedAPIs()) + } + + intersecting := len(add.Intersection(providedAPIIntersection)) > 0 + subset := add.IsSubset(group.ProvidedAPIs()) + + if subset && intersecting { + return RemoveAPIs + } + + if !subset && intersecting { + return APIConflict + } + + if !subset { + return AddAPIs + } + + return NoAPIConflict +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/labeler.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/labeler.go new file mode 100644 index 0000000000..cf408ef00d --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/labeler.go @@ -0,0 +1,76 @@ +package resolver + +import ( + "github.com/operator-framework/operator-registry/pkg/registry" + extv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" + "k8s.io/apimachinery/pkg/labels" +) + +const ( + // APILabelKeyPrefix is the key prefix for a CSV's APIs label + APILabelKeyPrefix = "olm.api." +) + +// LabelSetsFor returns API label sets for the given object. +// Concrete types other than OperatorSurface and CustomResource definition no-op. +func LabelSetsFor(obj interface{}) ([]labels.Set, error) { + switch v := obj.(type) { + case OperatorSurface: + return labelSetsForOperatorSurface(v) + case *extv1beta1.CustomResourceDefinition: + return labelSetsForCRD(v) + default: + return nil, nil + } +} + +func labelSetsForOperatorSurface(surface OperatorSurface) ([]labels.Set, error) { + labelSet := labels.Set{} + for key := range surface.ProvidedAPIs().StripPlural() { + hash, err := APIKeyToGVKHash(key) + if err != nil { + return nil, err + } + labelSet[APILabelKeyPrefix+hash] = "provided" + } + for key := range surface.RequiredAPIs().StripPlural() { + hash, err := APIKeyToGVKHash(key) + if err != nil { + return nil, err + } + labelSet[APILabelKeyPrefix+hash] = "required" + } + + return []labels.Set{labelSet}, nil +} + +func labelSetsForCRD(crd *extv1beta1.CustomResourceDefinition) ([]labels.Set, error) { + labelSets := []labels.Set{} + if crd == nil { + return labelSets, nil + } + + // Add label sets for each version + for _, version := range crd.Spec.Versions { + hash, err := APIKeyToGVKHash(registry.APIKey{ + Group: crd.Spec.Group, + Version: version.Name, + Kind: crd.Spec.Names.Kind, + }) + if err != nil { + return nil, err + } + key := APILabelKeyPrefix + hash + sets := []labels.Set{ + { + key: "provided", + }, + { + key: "required", + }, + } + labelSets = append(labelSets, sets...) + } + + return labelSets, nil +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/operators.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/operators.go new file mode 100644 index 0000000000..b1b22d93fc --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/operators.go @@ -0,0 +1,321 @@ +package resolver + +import ( + "fmt" + "hash/fnv" + "sort" + "strings" + + "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + opregistry "github.com/operator-framework/operator-registry/pkg/registry" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +type CatalogKey struct { + Name string + Namespace string +} + +func (k *CatalogKey) String() string { + return fmt.Sprintf("%s/%s", k.Name, k.Namespace) +} + +type APISet map[opregistry.APIKey]struct{} + +func EmptyAPISet() APISet { + return map[opregistry.APIKey]struct{}{} +} + +func (s APISet) PopAPIKey() *opregistry.APIKey { + for a := range s { + api := &opregistry.APIKey{ + Group: a.Group, + Version: a.Version, + Kind: a.Kind, + Plural: a.Plural, + } + delete(s, a) + return api + } + return nil +} + +func GVKStringToProvidedAPISet(gvksStr string) APISet { + set := make(APISet) + // TODO: Should we make gvk strings lowercase to avoid issues with user set gvks? + gvks := strings.Split(strings.Replace(gvksStr, " ", "", -1), ",") + for _, gvkStr := range gvks { + gvk, _ := schema.ParseKindArg(gvkStr) + if gvk != nil { + set[opregistry.APIKey{Group: gvk.Group, Version: gvk.Version, Kind: gvk.Kind}] = struct{}{} + } + } + + return set +} + +func APIKeyToGVKString(key opregistry.APIKey) string { + // TODO: Add better validation of GVK + return strings.Join([]string{key.Kind, key.Version, key.Group}, ".") +} + +func APIKeyToGVKHash(key opregistry.APIKey) (string, error) { + hash := fnv.New64a() + if _, err := hash.Write([]byte(APIKeyToGVKString(key))); err != nil { + return "", err + } + return fmt.Sprintf("%x", hash.Sum64()), nil +} + +func (s APISet) String() string { + gvkStrs := make([]string, len(s)) + i := 0 + for api := range s { + // TODO: Only add valid GVK strings + gvkStrs[i] = APIKeyToGVKString(api) + i++ + } + sort.Strings(gvkStrs) + + return strings.Join(gvkStrs, ",") +} + +// TODO: Generalize set logic and make an abstraction for sets to implemement to feed into it. + +// Union returns the union of the APISet and the given list of APISets +func (s APISet) Union(sets ...APISet) APISet { + union := make(APISet) + for api := range s { + union[api] = struct{}{} + } + for _, set := range sets { + for api := range set { + union[api] = struct{}{} + } + } + + return union +} + +// Intersection returns the intersection of the APISet and the given list of APISets +func (s APISet) Intersection(sets ...APISet) APISet { + intersection := make(APISet) + for _, set := range sets { + for api := range set { + if _, ok := s[api]; ok { + intersection[api] = struct{}{} + } + } + } + + return intersection +} + +func (s APISet) Difference(set APISet) APISet { + difference := make(APISet).Union(s) + for api := range set { + if _, ok := difference[api]; ok { + delete(difference, api) + } + } + + return difference +} + +// IsSubset returns true if the APISet is a subset of the given one +func (s APISet) IsSubset(set APISet) bool { + for api := range s { + if _, ok := set[api]; !ok { + return false + } + } + + return true +} + +// StripPlural returns the APISet with the Plural field of all APIKeys removed +func (s APISet) StripPlural() APISet { + set := make(APISet) + for api := range s { + set[opregistry.APIKey{Group: api.Group, Version: api.Version, Kind: api.Kind}] = struct{}{} + } + + return set +} + +type APIOwnerSet map[opregistry.APIKey]OperatorSurface + +func EmptyAPIOwnerSet() APIOwnerSet { + return map[opregistry.APIKey]OperatorSurface{} +} + +type OperatorSet map[string]OperatorSurface + +func EmptyOperatorSet() OperatorSet { + return map[string]OperatorSurface{} +} + +// Snapshot returns a new set, pointing to the same values +func (o OperatorSet) Snapshot() OperatorSet { + out := make(map[string]OperatorSurface) + for key, val := range o { + out[key] = val + } + return out +} + +type APIMultiOwnerSet map[opregistry.APIKey]OperatorSet + +func EmptyAPIMultiOwnerSet() APIMultiOwnerSet { + return map[opregistry.APIKey]OperatorSet{} +} + +func (s APIMultiOwnerSet) PopAPIKey() *opregistry.APIKey { + for a := range s { + api := &opregistry.APIKey{ + Group: a.Group, + Version: a.Version, + Kind: a.Kind, + Plural: a.Plural, + } + delete(s, a) + return api + } + return nil +} + +func (s APIMultiOwnerSet) PopAPIRequirers() OperatorSet { + requirers := EmptyOperatorSet() + for a := range s { + for key, op := range s[a] { + requirers[key] = op + } + delete(s, a) + return requirers + } + return nil +} + +type OperatorSourceInfo struct { + Package string + Channel string + StartingCSV string + Catalog CatalogKey +} + +func (i *OperatorSourceInfo) String() string { + return fmt.Sprintf("%s/%s in %s/%s", i.Package, i.Channel, i.Catalog.Name, i.Catalog.Namespace) +} + +var ExistingOperator = OperatorSourceInfo{"", "", "", CatalogKey{"", ""}} + +// OperatorSurface describes the API surfaces provided and required by an Operator. +type OperatorSurface interface { + ProvidedAPIs() APISet + RequiredAPIs() APISet + Identifier() string + Replaces() string + SourceInfo() *OperatorSourceInfo + Bundle() *opregistry.Bundle +} + +type Operator struct { + name string + replaces string + providedAPIs APISet + requiredAPIs APISet + bundle *opregistry.Bundle + sourceInfo *OperatorSourceInfo +} + +var _ OperatorSurface = &Operator{} + +func NewOperatorFromBundle(bundle *opregistry.Bundle, startingCSV string, sourceKey CatalogKey) (*Operator, error) { + csv, err := bundle.ClusterServiceVersion() + if err != nil { + return nil, err + } + providedAPIs, err := bundle.ProvidedAPIs() + if err != nil { + return nil, err + } + requiredAPIs, err := bundle.RequiredAPIs() + if err != nil { + return nil, err + } + return &Operator{ + name: csv.GetName(), + replaces: csv.Spec.Replaces, + providedAPIs: providedAPIs, + requiredAPIs: requiredAPIs, + bundle: bundle, + sourceInfo: &OperatorSourceInfo{ + Package: bundle.Package, + Channel: bundle.Channel, + StartingCSV: startingCSV, + Catalog: sourceKey, + }, + }, nil +} + +func NewOperatorFromCSV(csv *v1alpha1.ClusterServiceVersion) (*Operator, error) { + providedAPIs := EmptyAPISet() + for _, crdDef := range csv.Spec.CustomResourceDefinitions.Owned { + parts := strings.SplitN(crdDef.Name, ".", 2) + if len(parts) < 2 { + return nil, fmt.Errorf("error parsing crd name: %s", crdDef.Name) + } + providedAPIs[opregistry.APIKey{Plural: parts[0], Group: parts[1], Version: crdDef.Version, Kind: crdDef.Kind}] = struct{}{} + } + for _, api := range csv.Spec.APIServiceDefinitions.Owned { + providedAPIs[opregistry.APIKey{Group: api.Group, Version: api.Version, Kind: api.Kind, Plural: api.Name}] = struct{}{} + } + + requiredAPIs := EmptyAPISet() + for _, crdDef := range csv.Spec.CustomResourceDefinitions.Required { + parts := strings.SplitN(crdDef.Name, ".", 2) + if len(parts) < 2 { + return nil, fmt.Errorf("error parsing crd name: %s", crdDef.Name) + } + requiredAPIs[opregistry.APIKey{Plural: parts[0], Group: parts[1], Version: crdDef.Version, Kind: crdDef.Kind}] = struct{}{} + } + for _, api := range csv.Spec.APIServiceDefinitions.Required { + requiredAPIs[opregistry.APIKey{Group: api.Group, Version: api.Version, Kind: api.Kind, Plural: api.Name}] = struct{}{} + } + + return &Operator{ + name: csv.GetName(), + replaces: csv.Spec.Replaces, + providedAPIs: providedAPIs, + requiredAPIs: requiredAPIs, + sourceInfo: &ExistingOperator, + }, nil +} + +func (o *Operator) ProvidedAPIs() APISet { + return o.providedAPIs +} + +func (o *Operator) RequiredAPIs() APISet { + return o.requiredAPIs +} + +func (o *Operator) Identifier() string { + return o.name +} + +func (o *Operator) Replaces() string { + return o.replaces +} + +func (o *Operator) Package() string { + return o.bundle.Package +} + +func (o *Operator) SourceInfo() *OperatorSourceInfo { + return o.sourceInfo +} + +func (o *Operator) Bundle() *opregistry.Bundle { + return o.bundle +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/querier.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/querier.go new file mode 100644 index 0000000000..26b924ad7b --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/querier.go @@ -0,0 +1,125 @@ +//go:generate counterfeiter -o fakes/fake_registry_client.go ../../../../vendor/github.com/operator-framework/operator-registry/pkg/client/client.go Interface +package resolver + +import ( + "context" + "fmt" + + "github.com/operator-framework/operator-registry/pkg/client" + opregistry "github.com/operator-framework/operator-registry/pkg/registry" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type SourceRef struct { + Address string + Client client.Interface + LastConnect metav1.Time + LastHealthy metav1.Time +} + +type SourceQuerier interface { + FindProvider(api opregistry.APIKey) (*opregistry.Bundle, *CatalogKey, error) + FindBundle(pkgName, channelName, bundleName string, initialSource CatalogKey) (*opregistry.Bundle, *CatalogKey, error) + FindLatestBundle(pkgName, channelName string, initialSource CatalogKey) (*opregistry.Bundle, *CatalogKey, error) + FindReplacement(bundleName, pkgName, channelName string, initialSource CatalogKey) (*opregistry.Bundle, *CatalogKey, error) + Queryable() error +} + +type NamespaceSourceQuerier struct { + sources map[CatalogKey]client.Interface +} + +var _ SourceQuerier = &NamespaceSourceQuerier{} + +func NewNamespaceSourceQuerier(sources map[CatalogKey]client.Interface) *NamespaceSourceQuerier { + return &NamespaceSourceQuerier{ + sources: sources, + } +} + +func (q *NamespaceSourceQuerier) Queryable() error { + if len(q.sources) == 0 { + return fmt.Errorf("no catalog sources available") + } + return nil +} + +func (q *NamespaceSourceQuerier) FindProvider(api opregistry.APIKey) (*opregistry.Bundle, *CatalogKey, error) { + for key, source := range q.sources { + if bundle, err := source.GetBundleThatProvides(context.TODO(), api.Group, api.Version, api.Kind); err == nil { + return bundle, &key, nil + } + if bundle, err := source.GetBundleThatProvides(context.TODO(), api.Plural+"."+api.Group, api.Version, api.Kind); err == nil { + return bundle, &key, nil + } + } + return nil, nil, fmt.Errorf("%s not provided by a package in any CatalogSource", api) +} + +func (q *NamespaceSourceQuerier) FindBundle(pkgName, channelName, bundleName string, initialSource CatalogKey) (*opregistry.Bundle, *CatalogKey, error) { + if initialSource.Name != "" && initialSource.Namespace != "" { + source, ok := q.sources[initialSource] + if !ok { + return nil, nil, fmt.Errorf("CatalogSource %s not found", initialSource) + } + + bundle, err := source.GetBundle(context.TODO(), pkgName, channelName, bundleName) + if err != nil { + return nil, nil, err + } + return bundle, &initialSource, nil + } + + for key, source := range q.sources { + bundle, err := source.GetBundle(context.TODO(), pkgName, channelName, bundleName) + if err == nil { + return bundle, &key, nil + } + } + return nil, nil, fmt.Errorf("%s/%s/%s not found in any available CatalogSource", pkgName, channelName, bundleName) +} + +func (q *NamespaceSourceQuerier) FindLatestBundle(pkgName, channelName string, initialSource CatalogKey) (*opregistry.Bundle, *CatalogKey, error) { + if initialSource.Name != "" && initialSource.Namespace != "" { + source, ok := q.sources[initialSource] + if !ok { + return nil, nil, fmt.Errorf("CatalogSource %s not found", initialSource) + } + + bundle, err := source.GetBundleInPackageChannel(context.TODO(), pkgName, channelName) + if err != nil { + return nil, nil, err + } + return bundle, &initialSource, nil + } + + for key, source := range q.sources { + bundle, err := source.GetBundleInPackageChannel(context.TODO(), pkgName, channelName) + if err == nil { + return bundle, &key, nil + } + } + return nil, nil, fmt.Errorf("%s/%s not found in any available CatalogSource", pkgName, channelName) +} + +func (q *NamespaceSourceQuerier) FindReplacement(bundleName, pkgName, channelName string, initialSource CatalogKey) (*opregistry.Bundle, *CatalogKey, error) { + if initialSource.Name != "" && initialSource.Namespace != "" { + source, ok := q.sources[initialSource] + if !ok { + return nil, nil, fmt.Errorf("CatalogSource %s not found", initialSource.Name) + } + bundle, err := source.GetReplacementBundleInPackageChannel(context.TODO(), bundleName, pkgName, channelName) + if err != nil { + return nil, nil, err + } + return bundle, &initialSource, nil + } + + for key, source := range q.sources { + bundle, err := source.GetReplacementBundleInPackageChannel(context.TODO(), bundleName, pkgName, channelName) + if err == nil { + return bundle, &key, nil + } + } + return nil, nil, fmt.Errorf("%s/%s not found in any available CatalogSource", pkgName, channelName) +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/rbac.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/rbac.go new file mode 100644 index 0000000000..8d0608ddd9 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/rbac.go @@ -0,0 +1,159 @@ +package resolver + +import ( + "fmt" + + corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apiserver/pkg/storage/names" + + "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install" + "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil" +) + +var generateName = func(base string) string { + return names.SimpleNameGenerator.GenerateName(base + "-") +} + +type OperatorPermissions struct { + ServiceAccount *corev1.ServiceAccount + Roles []*rbacv1.Role + RoleBindings []*rbacv1.RoleBinding + ClusterRoles []*rbacv1.ClusterRole + ClusterRoleBindings []*rbacv1.ClusterRoleBinding +} + +func NewOperatorPermissions(serviceAccount *corev1.ServiceAccount) *OperatorPermissions { + return &OperatorPermissions{ + ServiceAccount: serviceAccount, + Roles: []*rbacv1.Role{}, + RoleBindings: []*rbacv1.RoleBinding{}, + ClusterRoles: []*rbacv1.ClusterRole{}, + ClusterRoleBindings: []*rbacv1.ClusterRoleBinding{}, + } +} + +func (o *OperatorPermissions) AddRole(role *rbacv1.Role) { + o.Roles = append(o.Roles, role) +} + +func (o *OperatorPermissions) AddRoleBinding(roleBinding *rbacv1.RoleBinding) { + o.RoleBindings = append(o.RoleBindings, roleBinding) +} + +func (o *OperatorPermissions) AddClusterRole(clusterRole *rbacv1.ClusterRole) { + o.ClusterRoles = append(o.ClusterRoles, clusterRole) +} + +func (o *OperatorPermissions) AddClusterRoleBinding(clusterRoleBinding *rbacv1.ClusterRoleBinding) { + o.ClusterRoleBindings = append(o.ClusterRoleBindings, clusterRoleBinding) +} + +func RBACForClusterServiceVersion(csv *v1alpha1.ClusterServiceVersion) (map[string]*OperatorPermissions, error) { + permissions := map[string]*OperatorPermissions{} + + // Use a StrategyResolver to get the strategy details + strategyResolver := install.StrategyResolver{} + strategy, err := strategyResolver.UnmarshalStrategy(csv.Spec.InstallStrategy) + if err != nil { + return nil, err + } + + // Assume the strategy is for a deployment + strategyDetailsDeployment, ok := strategy.(*install.StrategyDetailsDeployment) + if !ok { + return nil, fmt.Errorf("could not assert strategy implementation as deployment for CSV %s", csv.GetName()) + } + + // Resolve Permissions + for _, permission := range strategyDetailsDeployment.Permissions { + // Create ServiceAccount if necessary + if _, ok := permissions[permission.ServiceAccountName]; !ok { + serviceAccount := &corev1.ServiceAccount{} + serviceAccount.SetNamespace(csv.GetNamespace()) + serviceAccount.SetName(permission.ServiceAccountName) + ownerutil.AddNonBlockingOwner(serviceAccount, csv) + + permissions[permission.ServiceAccountName] = NewOperatorPermissions(serviceAccount) + } + + // Create Role + role := &rbacv1.Role{ + ObjectMeta: metav1.ObjectMeta{ + Name: generateName(csv.GetName()), + Namespace: csv.GetNamespace(), + OwnerReferences: []metav1.OwnerReference{ownerutil.NonBlockingOwner(csv)}, + Labels: ownerutil.OwnerLabel(csv, v1alpha1.ClusterServiceVersionKind), + }, + Rules: permission.Rules, + } + permissions[permission.ServiceAccountName].AddRole(role) + + // Create RoleBinding + roleBinding := &rbacv1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: generateName(fmt.Sprintf("%s-%s", role.GetName(), permission.ServiceAccountName)), + Namespace: csv.GetNamespace(), + OwnerReferences: []metav1.OwnerReference{ownerutil.NonBlockingOwner(csv)}, + Labels: ownerutil.OwnerLabel(csv, v1alpha1.ClusterServiceVersionKind), + }, + RoleRef: rbacv1.RoleRef{ + Kind: "Role", + Name: role.GetName(), + APIGroup: rbacv1.GroupName}, + Subjects: []rbacv1.Subject{{ + Kind: "ServiceAccount", + Name: permission.ServiceAccountName, + Namespace: csv.GetNamespace(), + }}, + } + permissions[permission.ServiceAccountName].AddRoleBinding(roleBinding) + } + + // Resolve ClusterPermissions as StepResources + for _, permission := range strategyDetailsDeployment.ClusterPermissions { + // Create ServiceAccount if necessary + if _, ok := permissions[permission.ServiceAccountName]; !ok { + serviceAccount := &corev1.ServiceAccount{} + serviceAccount.SetName(permission.ServiceAccountName) + ownerutil.AddNonBlockingOwner(serviceAccount, csv) + + permissions[permission.ServiceAccountName] = NewOperatorPermissions(serviceAccount) + } + + // Create ClusterRole + role := &rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: generateName(csv.GetName()), + OwnerReferences: []metav1.OwnerReference{ownerutil.NonBlockingOwner(csv)}, + Labels: ownerutil.OwnerLabel(csv, v1alpha1.ClusterServiceVersionKind), + }, + Rules: permission.Rules, + } + permissions[permission.ServiceAccountName].AddClusterRole(role) + + // Create ClusterRoleBinding + roleBinding := &rbacv1.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: generateName(fmt.Sprintf("%s-%s", role.GetName(), permission.ServiceAccountName)), + Namespace: csv.GetNamespace(), + OwnerReferences: []metav1.OwnerReference{ownerutil.NonBlockingOwner(csv)}, + Labels: ownerutil.OwnerLabel(csv, v1alpha1.ClusterServiceVersionKind), + }, + RoleRef: rbacv1.RoleRef{ + Kind: "ClusterRole", + Name: role.GetName(), + APIGroup: rbacv1.GroupName, + }, + Subjects: []rbacv1.Subject{{ + Kind: "ServiceAccount", + Name: permission.ServiceAccountName, + Namespace: csv.GetNamespace(), + }}, + } + permissions[permission.ServiceAccountName].AddClusterRoleBinding(roleBinding) + } + return permissions, nil +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/resolver.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/resolver.go index 636cc47993..ec902fc308 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/resolver.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/resolver.go @@ -1,247 +1,162 @@ +//go:generate counterfeiter -o fakes/fake_registry_client.go ../../../../vendor/github.com/operator-framework/operator-registry/pkg/client/client.go Interface +//go:generate counterfeiter -o ../../../fakes/fake_resolver.go . Resolver package resolver import ( "fmt" + "time" - olmerrors "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/errors" - log "github.com/sirupsen/logrus" - "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" - "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry" + v1alpha1listers "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1alpha1" + "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister" ) -// DependencyResolver defines how a something that resolves dependencies (CSVs, CRDs, etc...) -// should behave -type DependencyResolver interface { - ResolveInstallPlan(sourceRefs []registry.SourceRef, existingCRDOwners map[string][]string, catalogLabelKey string, plan *v1alpha1.InstallPlan) ([]v1alpha1.Step, []registry.ResourceKey, error) -} - -// MultiSourceResolver resolves resolves dependencies from multiple CatalogSources -type MultiSourceResolver struct{} - -// ResolveInstallPlan resolves the given InstallPlan with all available sources -func (resolver *MultiSourceResolver) ResolveInstallPlan(sourceRefs []registry.SourceRef, existingCRDOwners map[string][]string, catalogLabelKey string, plan *v1alpha1.InstallPlan) ([]v1alpha1.Step, []registry.ResourceKey, error) { - srm := make(stepResourceMap) - var usedSourceKeys []registry.ResourceKey - - for _, csvName := range plan.Spec.ClusterServiceVersionNames { - csvSRM, used, err := resolver.resolveCSV(sourceRefs, existingCRDOwners, catalogLabelKey, plan.Namespace, csvName) - if err != nil { - // Could not resolve CSV in any source - return nil, nil, err - } - - srm.Combine(csvSRM) - usedSourceKeys = append(used, usedSourceKeys...) - } +var timeNow = func() metav1.Time { return metav1.NewTime(time.Now().UTC()) } - return srm.Plan(), usedSourceKeys, nil +type Resolver interface { + ResolveSteps(namespace string, sourceQuerier SourceQuerier) ([]*v1alpha1.Step, []*v1alpha1.Subscription, error) } -func (resolver *MultiSourceResolver) resolveCSV(sourceRefs []registry.SourceRef, existingCRDOwners map[string][]string, catalogLabelKey, planNamespace, csvName string) (stepResourceMap, []registry.ResourceKey, error) { - log.Debugf("resolving CSV with name: %s", csvName) - - steps := make(stepResourceMap) - csvNamesToBeResolved := []string{csvName} - var usedSourceKeys []registry.ResourceKey - - for len(csvNamesToBeResolved) != 0 { - // Pop off a CSV name. - currentName := csvNamesToBeResolved[0] - csvNamesToBeResolved = csvNamesToBeResolved[1:] - - // If this CSV is already resolved, continue. - if _, exists := steps[currentName]; exists { - continue - } - - var csvSourceKey registry.ResourceKey - var csv *v1alpha1.ClusterServiceVersion - var err error - - // Attempt to Get the full CSV object for the name from any - for _, ref := range sourceRefs { - csv, err = ref.Source.FindCSVByName(currentName) - - if err == nil { - // Found CSV - csvSourceKey = ref.SourceKey - break - } - - } - - if err != nil { - // Couldn't find CSV in any CatalogSource - return nil, nil, err - } - - log.Debugf("found %s", csv.GetName()) - usedSourceKeys = append(usedSourceKeys, csvSourceKey) - - // Resolve each owned or required CRD for the CSV. - for _, crdDesc := range csv.GetAllCRDDescriptions() { - // Attempt to get CRD from same catalog source CSV was found in - crdSteps, owner, err := resolver.resolveCRDDescription(sourceRefs, existingCRDOwners, catalogLabelKey, planNamespace, crdDesc, csv.OwnsCRD(crdDesc.Name)) - if err != nil { - return nil, nil, err - } - - // If a different owner was resolved, add it to the list. - if owner != "" && owner != currentName { - csvNamesToBeResolved = append(csvNamesToBeResolved, owner) - } else { - // Add the resolved steps to the plan. - steps[currentName] = append(steps[currentName], crdSteps...) - } - - } - - // Manually override the namespace and create the final step for the CSV, - // which is for the CSV itself. - csv.SetNamespace(planNamespace) - - // Add the sourcename as a label on the CSV, so that we know where it came from - labels := csv.GetLabels() - if labels == nil { - labels = map[string]string{} - } - labels[catalogLabelKey] = csvSourceKey.Name - csv.SetLabels(labels) - - step, err := v1alpha1.NewStepResourceFromCSV(csv) - if err != nil { - return nil, nil, err - } +type OperatorsV1alpha1Resolver struct { + subLister v1alpha1listers.SubscriptionLister + csvLister v1alpha1listers.ClusterServiceVersionLister +} - // Set the catalog source name and namespace - step.CatalogSource = csvSourceKey.Name - step.CatalogSourceNamespace = csvSourceKey.Namespace +var _ Resolver = &OperatorsV1alpha1Resolver{} - // Add the final step for the CSV to the plan. - log.Infof("finished step: %s", step.Name) - steps[currentName] = append(steps[currentName], step) +func NewOperatorsV1alpha1Resolver(lister operatorlister.OperatorLister) *OperatorsV1alpha1Resolver { + return &OperatorsV1alpha1Resolver{ + subLister: lister.OperatorsV1alpha1().SubscriptionLister(), + csvLister: lister.OperatorsV1alpha1().ClusterServiceVersionLister(), } - - return steps, usedSourceKeys, nil } -func (resolver *MultiSourceResolver) resolveCRDDescription(sourceRefs []registry.SourceRef, existingCRDOwners map[string][]string, catalogLabelKey, planNamespace string, crdDesc v1alpha1.CRDDescription, owned bool) ([]v1alpha1.StepResource, string, error) { - log.Debugf("resolving %#v", crdDesc) - var steps []v1alpha1.StepResource - - crdKey := registry.CRDKey{ - Kind: crdDesc.Kind, - Name: crdDesc.Name, - Version: crdDesc.Version, +func (r *OperatorsV1alpha1Resolver) ResolveSteps(namespace string, sourceQuerier SourceQuerier) ([]*v1alpha1.Step, []*v1alpha1.Subscription, error) { + if err := sourceQuerier.Queryable(); err != nil { + return nil, nil, err } - var crdSourceKey registry.ResourceKey - var crd *v1beta1.CustomResourceDefinition - var source registry.Source - var err error - - // Attempt to find the CRD in any other source if the CRD is not owned - for _, ref := range sourceRefs { - source = ref.Source - crd, err = source.FindCRDByKey(crdKey) + // create a generation - a representation of the current set of installed operators and their provided/required apis + allCSVs, err := r.csvLister.ClusterServiceVersions(namespace).List(labels.Everything()) + if err != nil { + return nil, nil, err + } - if err == nil { - // Found the CRD - crdSourceKey = ref.SourceKey - break + // TODO: build this index ahead of time + // omit copied csvs from generation - they indicate that apis are provided to the namespace, not by the namespace + var csvs []*v1alpha1.ClusterServiceVersion + for _, c := range allCSVs { + if !c.IsCopied() { + csvs = append(csvs, c) } } + subs, err := r.subLister.Subscriptions(namespace).List(labels.Everything()) if err != nil { - return nil, "", err + return nil, nil, err } - if owned { - // Label CRD with catalog source - labels := crd.GetLabels() - if labels == nil { - labels = map[string]string{} - } - labels[catalogLabelKey] = crdSourceKey.Name - crd.SetLabels(labels) + gen, err := NewGenerationFromCluster(csvs, subs) + if err != nil { + return nil, nil, err + } - // Add CRD Step - crdSteps, err := v1alpha1.NewStepResourcesFromCRD(crd) - if err != nil { - return nil, "", err - } + // create a map of operatorsourceinfo (subscription+catalogsource data) to the original subscriptions + subMap := r.sourceInfoToSubscriptions(subs) + // get a list of new operators to add to the generation + add := r.sourceInfoForNewSubscriptions(namespace, subMap) - // Set the catalog source name and namespace - for _, s := range crdSteps { - s.CatalogSource = crdSourceKey.Name - s.CatalogSourceNamespace = crdSourceKey.Namespace - steps = append(steps, s) - } - return steps, "", nil + // evolve a generation by resolving the set of subscriptions (in `add`) by querying with `source` + // and taking the current generation (in `gen`) into account + if err := NewNamespaceGenerationEvolver(sourceQuerier, gen).Evolve(add); err != nil { + return nil, nil, err } - csvs, err := source.ListLatestCSVsForCRD(crdKey) - if err != nil { - return nil, "", err - } - if len(csvs) == 0 { - return nil, "", fmt.Errorf("Unknown CRD %s", crdKey) - } + // if there's no error, we were able to satsify all constraints in the subscription set, so we calculate what + // changes to persist to the cluster and write them out as `steps` + steps := []*v1alpha1.Step{} + updatedSubs := []*v1alpha1.Subscription{} + for name, op := range gen.Operators() { + _, isAdded := add[*op.SourceInfo()] + existingSubscription, subExists := subMap[*op.SourceInfo()] - var ownerName string - owners := existingCRDOwners[crdKey.Name] - switch len(owners) { - case 0: - // No pre-existing owner found - for _, csv := range csvs { - // Check for the default channel - if csv.IsDefaultChannel { - ownerName = csv.CSV.Name - break - } + // subscription exists and is up to date + if subExists && existingSubscription.Status.CurrentCSV == op.Identifier() && !isAdded { + continue } - case 1: - ownerName = owners[0] - default: - return nil, "", olmerrors.NewMultipleExistingCRDOwnersError(owners, crdKey.Name, planNamespace) - } - // Check empty name - if ownerName == "" { - log.Infof("No preexisting CSV or default channel found for owners of CRD %v", crdKey) - ownerName = csvs[0].CSV.Name - } + // add steps for any new bundle + if op.Bundle() != nil { + bundleSteps, err := NewStepResourceFromBundle(op.Bundle(), namespace, op.SourceInfo().Catalog.Name, op.SourceInfo().Catalog.Namespace) + if err != nil { + return nil, nil, fmt.Errorf("failed to turn bundle into steps") + } + for _, s := range bundleSteps { + steps = append(steps, &v1alpha1.Step{ + Resolving: name, + Resource: s, + Status: v1alpha1.StepStatusUnknown, + }) + } - log.Infof("Found %v owner %s", crdKey, ownerName) - return nil, ownerName, nil -} + // add steps for subscriptions for bundles that were added through resolution + if !subExists { + subStep, err := NewSubscriptionStepResource(namespace, *op.SourceInfo()) + if err != nil { + return nil, nil, err + } + steps = append(steps, &v1alpha1.Step{ + Resolving: name, + Resource: subStep, + Status: v1alpha1.StepStatusUnknown, + }) + } + } -type stepResourceMap map[string][]v1alpha1.StepResource - -func (srm stepResourceMap) Plan() []v1alpha1.Step { - steps := make([]v1alpha1.Step, 0) - for csvName, stepResSlice := range srm { - for _, stepRes := range stepResSlice { - steps = append(steps, v1alpha1.Step{ - Resolving: csvName, - Resource: stepRes, - Status: v1alpha1.StepStatusUnknown, - }) + // update existing subscriptions status + if subExists && existingSubscription.Status.CurrentCSV != op.Identifier() { + existingSubscription.Status.CurrentCSV = op.Identifier() + updatedSubs = append(updatedSubs, existingSubscription) } } - return steps + return steps, updatedSubs, nil } -func (srm stepResourceMap) Combine(y stepResourceMap) { - for csvName, stepResSlice := range y { - // Skip any redundant steps. - if _, alreadyExists := srm[csvName]; alreadyExists { +func (r *OperatorsV1alpha1Resolver) sourceInfoForNewSubscriptions(namespace string, subs map[OperatorSourceInfo]*v1alpha1.Subscription) (add map[OperatorSourceInfo]struct{}) { + add = make(map[OperatorSourceInfo]struct{}) + for key, sub := range subs { + if sub.Status.CurrentCSV == "" { + add[key] = struct{}{} continue } + csv, err := r.csvLister.ClusterServiceVersions(namespace).Get(sub.Status.CurrentCSV) + if csv == nil || errors.IsNotFound(err) { + add[key] = struct{}{} + } + } + return +} - srm[csvName] = stepResSlice +func (r *OperatorsV1alpha1Resolver) sourceInfoToSubscriptions(subs []*v1alpha1.Subscription) (add map[OperatorSourceInfo]*v1alpha1.Subscription) { + add = make(map[OperatorSourceInfo]*v1alpha1.Subscription) + for _, s := range subs { + startingCSV := s.Spec.StartingCSV + if s.Status.CurrentCSV != "" { + // If a csv has previously been resolved for the operator, don't enable + // a starting csv search. + startingCSV = "" + } + add[OperatorSourceInfo{ + Package: s.Spec.Package, + Channel: s.Spec.Channel, + StartingCSV: startingCSV, + Catalog: CatalogKey{Name: s.Spec.CatalogSource, Namespace: s.Spec.CatalogSourceNamespace}, + }] = s.DeepCopy() } + return } diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/steps.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/steps.go new file mode 100644 index 0000000000..1dfa436f57 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/steps.go @@ -0,0 +1,162 @@ +package resolver + +import ( + "bytes" + "fmt" + "strings" + + "github.com/operator-framework/operator-registry/pkg/registry" + extScheme "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + k8sjson "k8s.io/apimachinery/pkg/runtime/serializer/json" + k8sscheme "k8s.io/client-go/kubernetes/scheme" + + "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil" +) + +var ( + scheme = runtime.NewScheme() +) + +func init() { + k8sscheme.AddToScheme(scheme) + extScheme.AddToScheme(scheme) + if err := v1alpha1.AddToScheme(scheme); err != nil { + panic(err) + } +} + +// NewStepResourceForObject returns a new StepResource for the provided object +func NewStepResourceFromObject(obj runtime.Object, catalogSourceName, catalogSourceNamespace string) (v1alpha1.StepResource, error) { + var resource v1alpha1.StepResource + + // set up object serializer + serializer := k8sjson.NewSerializer(k8sjson.DefaultMetaFactory, scheme, scheme, false) + + // create an object manifest + var manifest bytes.Buffer + err := serializer.Encode(obj, &manifest) + if err != nil { + return resource, err + } + + if err := ownerutil.InferGroupVersionKind(obj); err != nil { + return resource, err + } + + gvk := obj.GetObjectKind().GroupVersionKind() + + metaObj, ok := obj.(metav1.Object) + if !ok { + return resource, fmt.Errorf("couldn't get object metadata") + } + + name := metaObj.GetName() + if name == "" { + name = metaObj.GetGenerateName() + } + + // create the resource + resource = v1alpha1.StepResource{ + Name: name, + Kind: gvk.Kind, + Group: gvk.Group, + Version: gvk.Version, + Manifest: manifest.String(), + CatalogSource: catalogSourceName, + CatalogSourceNamespace: catalogSourceNamespace, + } + + return resource, nil +} + +func NewSubscriptionStepResource(namespace string, info OperatorSourceInfo) (v1alpha1.StepResource, error) { + return NewStepResourceFromObject(&v1alpha1.Subscription{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: namespace, + Name: strings.Join([]string{info.Package, info.Channel, info.Catalog.Name, info.Catalog.Namespace}, "-"), + }, + Spec: &v1alpha1.SubscriptionSpec{ + CatalogSource: info.Catalog.Name, + CatalogSourceNamespace: info.Catalog.Namespace, + Package: info.Package, + Channel: info.Channel, + InstallPlanApproval: v1alpha1.ApprovalAutomatic, + }, + }, info.Catalog.Name, info.Catalog.Namespace) +} + +func NewStepResourceFromBundle(bundle *registry.Bundle, namespace, catalogSourceName, catalogSourceNamespace string) ([]v1alpha1.StepResource, error) { + steps := []v1alpha1.StepResource{} + + csv, err := bundle.ClusterServiceVersion() + if err != nil { + return nil, err + } + + csv.SetNamespace(namespace) + + for _, object := range bundle.Objects { + step, err := NewStepResourceFromObject(object, catalogSourceName, catalogSourceNamespace) + if err != nil { + return nil, err + } + steps = append(steps, step) + } + + operatorServiceAccountSteps, err := NewServiceAccountStepResources(csv, catalogSourceName, catalogSourceNamespace) + if err != nil { + return nil, err + } + steps = append(steps, operatorServiceAccountSteps...) + return steps, nil +} + +// NewServiceAccountStepResources returns a list of step resources required to satisfy the RBAC requirements of the given CSV's InstallStrategy +func NewServiceAccountStepResources(csv *v1alpha1.ClusterServiceVersion, catalogSourceName, catalogSourceNamespace string) ([]v1alpha1.StepResource, error) { + var rbacSteps []v1alpha1.StepResource + + operatorPermissions, err := RBACForClusterServiceVersion(csv) + if err != nil { + return nil, err + } + + for _, perms := range operatorPermissions { + step, err := NewStepResourceFromObject(perms.ServiceAccount, catalogSourceName, catalogSourceNamespace) + if err != nil { + return nil, err + } + rbacSteps = append(rbacSteps, step) + for _, role := range perms.Roles { + step, err := NewStepResourceFromObject(role, catalogSourceName, catalogSourceNamespace) + if err != nil { + return nil, err + } + rbacSteps = append(rbacSteps, step) + } + for _, roleBinding := range perms.RoleBindings { + step, err := NewStepResourceFromObject(roleBinding, catalogSourceName, catalogSourceNamespace) + if err != nil { + return nil, err + } + rbacSteps = append(rbacSteps, step) + } + for _, clusterRole := range perms.ClusterRoles { + step, err := NewStepResourceFromObject(clusterRole, catalogSourceName, catalogSourceNamespace) + if err != nil { + return nil, err + } + rbacSteps = append(rbacSteps, step) + } + for _, clusterRoleBinding := range perms.ClusterRoleBindings { + step, err := NewStepResourceFromObject(clusterRoleBinding, catalogSourceName, catalogSourceNamespace) + if err != nil { + return nil, err + } + rbacSteps = append(rbacSteps, step) + } + } + return rbacSteps, nil +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/types.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/types.go index c79da4412d..473c50c1f0 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/types.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/types.go @@ -1,36 +1,11 @@ -//go:generate counterfeiter -o ../../fakes/fake_registry_source.go types.go Source - package registry -import ( - "fmt" - - "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" - - "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" +const ( + ConfigMapCRDName = "customResourceDefinitions" + ConfigMapCSVName = "clusterServiceVersions" + ConfigMapPackageName = "packages" ) -// Catalog Source -// - Map name to ClusterServiceVersion -// - Map CRD to CRD definition -// - Map CRD to ClusterServiceVersion that manages it - -type Source interface { - FindCSVForPackageNameUnderChannel(packageName string, channelName string) (*v1alpha1.ClusterServiceVersion, error) - FindReplacementCSVForPackageNameUnderChannel(packageName string, channelName string, csvName string) (*v1alpha1.ClusterServiceVersion, error) - AllPackages() map[string]PackageManifest - - // Deprecated: Switch to FindReplacementCSVForPackageNameUnderChannel when the caller has package and channel - // information. - FindReplacementCSVForName(name string) (*v1alpha1.ClusterServiceVersion, error) - - FindCSVByName(name string) (*v1alpha1.ClusterServiceVersion, error) - ListServices() ([]v1alpha1.ClusterServiceVersion, error) - - FindCRDByKey(key CRDKey) (*v1beta1.CustomResourceDefinition, error) - ListLatestCSVsForCRD(key CRDKey) ([]CSVAndChannelInfo, error) -} - // ResourceKey contains metadata to uniquely identify a resource type ResourceKey struct { Name string @@ -38,41 +13,6 @@ type ResourceKey struct { Namespace string } -// SourceRef associates a Source with it's SourceKey -type SourceRef struct { - SourceKey ResourceKey - Source Source -} - -// CRDKey contains metadata needed to uniquely identify a CRD -type CRDKey struct { - Kind string - Name string - Version string -} - -func (k CRDKey) String() string { - return fmt.Sprintf("%s/%s/%s", k.Kind, k.Name, k.Version) -} - -// CSVAndChannelInfo holds information about a CSV and the channel in which it lives. -type CSVAndChannelInfo struct { - // CSV is the CSV found. - CSV *v1alpha1.ClusterServiceVersion - - // Channel is the channel that "contains" this CSV, as it is declared as part of the channel. - Channel PackageChannel - - // IsDefaultChannel returns true iff the channel is the default channel for the package. - IsDefaultChannel bool -} - -// CSVMetadata holds the necessary information to locate a particular CSV in the catalog -type CSVMetadata struct { - Name string - Version string -} - // PackageManifest holds information about a package, which is a reference to one (or more) // channels under a single package. type PackageManifest struct { @@ -82,7 +22,7 @@ type PackageManifest struct { // Channels are the declared channels for the package, ala `stable` or `alpha`. Channels []PackageChannel `json:"channels"` - // DefaultChannelName is, if specified, the name of the default channel for the package. The + // DefaultChannel is, if specified, the name of the default channel for the package. The // default channel will be installed if no other channel is explicitly given. If the package // has a single channel, then that channel is implicitly the default. DefaultChannelName string `json:"defaultChannel"` @@ -106,7 +46,7 @@ type PackageChannel struct { // Name is the name of the channel, e.g. `alpha` or `stable` Name string `json:"name"` - // CurrentCSVName defines a reference to the CSV holding the version of this package currently + // CurrentCSV defines a reference to the CSV holding the version of this package currently // for the channel. CurrentCSVName string `json:"currentCSV"` } @@ -115,8 +55,3 @@ type PackageChannel struct { func (pc PackageChannel) IsDefaultChannel(pm PackageManifest) bool { return pc.Name == pm.DefaultChannelName || len(pm.Channels) == 1 } - -type SubscriptionKey struct { - Name string - Namespace string -} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/client-go/listers/fake_v1_service_account_lister.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/client-go/listers/fake_v1_service_account_lister.go new file mode 100644 index 0000000000..1593d87f6f --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/client-go/listers/fake_v1_service_account_lister.go @@ -0,0 +1,190 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package listers + +import ( + sync "sync" + + v1 "k8s.io/api/core/v1" + labels "k8s.io/apimachinery/pkg/labels" + v1a "k8s.io/client-go/listers/core/v1" +) + +type FakeServiceAccountLister struct { + ListStub func(labels.Selector) ([]*v1.ServiceAccount, error) + listMutex sync.RWMutex + listArgsForCall []struct { + arg1 labels.Selector + } + listReturns struct { + result1 []*v1.ServiceAccount + result2 error + } + listReturnsOnCall map[int]struct { + result1 []*v1.ServiceAccount + result2 error + } + ServiceAccountsStub func(string) v1a.ServiceAccountNamespaceLister + serviceAccountsMutex sync.RWMutex + serviceAccountsArgsForCall []struct { + arg1 string + } + serviceAccountsReturns struct { + result1 v1a.ServiceAccountNamespaceLister + } + serviceAccountsReturnsOnCall map[int]struct { + result1 v1a.ServiceAccountNamespaceLister + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *FakeServiceAccountLister) List(arg1 labels.Selector) ([]*v1.ServiceAccount, error) { + fake.listMutex.Lock() + ret, specificReturn := fake.listReturnsOnCall[len(fake.listArgsForCall)] + fake.listArgsForCall = append(fake.listArgsForCall, struct { + arg1 labels.Selector + }{arg1}) + fake.recordInvocation("List", []interface{}{arg1}) + fake.listMutex.Unlock() + if fake.ListStub != nil { + return fake.ListStub(arg1) + } + if specificReturn { + return ret.result1, ret.result2 + } + fakeReturns := fake.listReturns + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *FakeServiceAccountLister) ListCallCount() int { + fake.listMutex.RLock() + defer fake.listMutex.RUnlock() + return len(fake.listArgsForCall) +} + +func (fake *FakeServiceAccountLister) ListCalls(stub func(labels.Selector) ([]*v1.ServiceAccount, error)) { + fake.listMutex.Lock() + defer fake.listMutex.Unlock() + fake.ListStub = stub +} + +func (fake *FakeServiceAccountLister) ListArgsForCall(i int) labels.Selector { + fake.listMutex.RLock() + defer fake.listMutex.RUnlock() + argsForCall := fake.listArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FakeServiceAccountLister) ListReturns(result1 []*v1.ServiceAccount, result2 error) { + fake.listMutex.Lock() + defer fake.listMutex.Unlock() + fake.ListStub = nil + fake.listReturns = struct { + result1 []*v1.ServiceAccount + result2 error + }{result1, result2} +} + +func (fake *FakeServiceAccountLister) ListReturnsOnCall(i int, result1 []*v1.ServiceAccount, result2 error) { + fake.listMutex.Lock() + defer fake.listMutex.Unlock() + fake.ListStub = nil + if fake.listReturnsOnCall == nil { + fake.listReturnsOnCall = make(map[int]struct { + result1 []*v1.ServiceAccount + result2 error + }) + } + fake.listReturnsOnCall[i] = struct { + result1 []*v1.ServiceAccount + result2 error + }{result1, result2} +} + +func (fake *FakeServiceAccountLister) ServiceAccounts(arg1 string) v1a.ServiceAccountNamespaceLister { + fake.serviceAccountsMutex.Lock() + ret, specificReturn := fake.serviceAccountsReturnsOnCall[len(fake.serviceAccountsArgsForCall)] + fake.serviceAccountsArgsForCall = append(fake.serviceAccountsArgsForCall, struct { + arg1 string + }{arg1}) + fake.recordInvocation("ServiceAccounts", []interface{}{arg1}) + fake.serviceAccountsMutex.Unlock() + if fake.ServiceAccountsStub != nil { + return fake.ServiceAccountsStub(arg1) + } + if specificReturn { + return ret.result1 + } + fakeReturns := fake.serviceAccountsReturns + return fakeReturns.result1 +} + +func (fake *FakeServiceAccountLister) ServiceAccountsCallCount() int { + fake.serviceAccountsMutex.RLock() + defer fake.serviceAccountsMutex.RUnlock() + return len(fake.serviceAccountsArgsForCall) +} + +func (fake *FakeServiceAccountLister) ServiceAccountsCalls(stub func(string) v1a.ServiceAccountNamespaceLister) { + fake.serviceAccountsMutex.Lock() + defer fake.serviceAccountsMutex.Unlock() + fake.ServiceAccountsStub = stub +} + +func (fake *FakeServiceAccountLister) ServiceAccountsArgsForCall(i int) string { + fake.serviceAccountsMutex.RLock() + defer fake.serviceAccountsMutex.RUnlock() + argsForCall := fake.serviceAccountsArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FakeServiceAccountLister) ServiceAccountsReturns(result1 v1a.ServiceAccountNamespaceLister) { + fake.serviceAccountsMutex.Lock() + defer fake.serviceAccountsMutex.Unlock() + fake.ServiceAccountsStub = nil + fake.serviceAccountsReturns = struct { + result1 v1a.ServiceAccountNamespaceLister + }{result1} +} + +func (fake *FakeServiceAccountLister) ServiceAccountsReturnsOnCall(i int, result1 v1a.ServiceAccountNamespaceLister) { + fake.serviceAccountsMutex.Lock() + defer fake.serviceAccountsMutex.Unlock() + fake.ServiceAccountsStub = nil + if fake.serviceAccountsReturnsOnCall == nil { + fake.serviceAccountsReturnsOnCall = make(map[int]struct { + result1 v1a.ServiceAccountNamespaceLister + }) + } + fake.serviceAccountsReturnsOnCall[i] = struct { + result1 v1a.ServiceAccountNamespaceLister + }{result1} +} + +func (fake *FakeServiceAccountLister) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.listMutex.RLock() + defer fake.listMutex.RUnlock() + fake.serviceAccountsMutex.RLock() + defer fake.serviceAccountsMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *FakeServiceAccountLister) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} + +var _ v1a.ServiceAccountLister = new(FakeServiceAccountLister) diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/client-go/listers/fake_v1_service_account_namespace_lister.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/client-go/listers/fake_v1_service_account_namespace_lister.go new file mode 100644 index 0000000000..0f8561a5a1 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/client-go/listers/fake_v1_service_account_namespace_lister.go @@ -0,0 +1,195 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package listers + +import ( + sync "sync" + + v1 "k8s.io/api/core/v1" + labels "k8s.io/apimachinery/pkg/labels" + v1a "k8s.io/client-go/listers/core/v1" +) + +type FakeServiceAccountNamespaceLister struct { + GetStub func(string) (*v1.ServiceAccount, error) + getMutex sync.RWMutex + getArgsForCall []struct { + arg1 string + } + getReturns struct { + result1 *v1.ServiceAccount + result2 error + } + getReturnsOnCall map[int]struct { + result1 *v1.ServiceAccount + result2 error + } + ListStub func(labels.Selector) ([]*v1.ServiceAccount, error) + listMutex sync.RWMutex + listArgsForCall []struct { + arg1 labels.Selector + } + listReturns struct { + result1 []*v1.ServiceAccount + result2 error + } + listReturnsOnCall map[int]struct { + result1 []*v1.ServiceAccount + result2 error + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *FakeServiceAccountNamespaceLister) Get(arg1 string) (*v1.ServiceAccount, error) { + fake.getMutex.Lock() + ret, specificReturn := fake.getReturnsOnCall[len(fake.getArgsForCall)] + fake.getArgsForCall = append(fake.getArgsForCall, struct { + arg1 string + }{arg1}) + fake.recordInvocation("Get", []interface{}{arg1}) + fake.getMutex.Unlock() + if fake.GetStub != nil { + return fake.GetStub(arg1) + } + if specificReturn { + return ret.result1, ret.result2 + } + fakeReturns := fake.getReturns + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *FakeServiceAccountNamespaceLister) GetCallCount() int { + fake.getMutex.RLock() + defer fake.getMutex.RUnlock() + return len(fake.getArgsForCall) +} + +func (fake *FakeServiceAccountNamespaceLister) GetCalls(stub func(string) (*v1.ServiceAccount, error)) { + fake.getMutex.Lock() + defer fake.getMutex.Unlock() + fake.GetStub = stub +} + +func (fake *FakeServiceAccountNamespaceLister) GetArgsForCall(i int) string { + fake.getMutex.RLock() + defer fake.getMutex.RUnlock() + argsForCall := fake.getArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FakeServiceAccountNamespaceLister) GetReturns(result1 *v1.ServiceAccount, result2 error) { + fake.getMutex.Lock() + defer fake.getMutex.Unlock() + fake.GetStub = nil + fake.getReturns = struct { + result1 *v1.ServiceAccount + result2 error + }{result1, result2} +} + +func (fake *FakeServiceAccountNamespaceLister) GetReturnsOnCall(i int, result1 *v1.ServiceAccount, result2 error) { + fake.getMutex.Lock() + defer fake.getMutex.Unlock() + fake.GetStub = nil + if fake.getReturnsOnCall == nil { + fake.getReturnsOnCall = make(map[int]struct { + result1 *v1.ServiceAccount + result2 error + }) + } + fake.getReturnsOnCall[i] = struct { + result1 *v1.ServiceAccount + result2 error + }{result1, result2} +} + +func (fake *FakeServiceAccountNamespaceLister) List(arg1 labels.Selector) ([]*v1.ServiceAccount, error) { + fake.listMutex.Lock() + ret, specificReturn := fake.listReturnsOnCall[len(fake.listArgsForCall)] + fake.listArgsForCall = append(fake.listArgsForCall, struct { + arg1 labels.Selector + }{arg1}) + fake.recordInvocation("List", []interface{}{arg1}) + fake.listMutex.Unlock() + if fake.ListStub != nil { + return fake.ListStub(arg1) + } + if specificReturn { + return ret.result1, ret.result2 + } + fakeReturns := fake.listReturns + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *FakeServiceAccountNamespaceLister) ListCallCount() int { + fake.listMutex.RLock() + defer fake.listMutex.RUnlock() + return len(fake.listArgsForCall) +} + +func (fake *FakeServiceAccountNamespaceLister) ListCalls(stub func(labels.Selector) ([]*v1.ServiceAccount, error)) { + fake.listMutex.Lock() + defer fake.listMutex.Unlock() + fake.ListStub = stub +} + +func (fake *FakeServiceAccountNamespaceLister) ListArgsForCall(i int) labels.Selector { + fake.listMutex.RLock() + defer fake.listMutex.RUnlock() + argsForCall := fake.listArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FakeServiceAccountNamespaceLister) ListReturns(result1 []*v1.ServiceAccount, result2 error) { + fake.listMutex.Lock() + defer fake.listMutex.Unlock() + fake.ListStub = nil + fake.listReturns = struct { + result1 []*v1.ServiceAccount + result2 error + }{result1, result2} +} + +func (fake *FakeServiceAccountNamespaceLister) ListReturnsOnCall(i int, result1 []*v1.ServiceAccount, result2 error) { + fake.listMutex.Lock() + defer fake.listMutex.Unlock() + fake.ListStub = nil + if fake.listReturnsOnCall == nil { + fake.listReturnsOnCall = make(map[int]struct { + result1 []*v1.ServiceAccount + result2 error + }) + } + fake.listReturnsOnCall[i] = struct { + result1 []*v1.ServiceAccount + result2 error + }{result1, result2} +} + +func (fake *FakeServiceAccountNamespaceLister) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.getMutex.RLock() + defer fake.getMutex.RUnlock() + fake.listMutex.RLock() + defer fake.listMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *FakeServiceAccountNamespaceLister) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} + +var _ v1a.ServiceAccountNamespaceLister = new(FakeServiceAccountNamespaceLister) diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/fake_api_intersection_reconciler.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/fake_api_intersection_reconciler.go new file mode 100644 index 0000000000..f67ba401da --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/fake_api_intersection_reconciler.go @@ -0,0 +1,114 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package fakes + +import ( + sync "sync" + + resolver "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver" +) + +type FakeAPIIntersectionReconciler struct { + ReconcileStub func(resolver.APISet, resolver.OperatorGroupSurface, ...resolver.OperatorGroupSurface) resolver.APIReconciliationResult + reconcileMutex sync.RWMutex + reconcileArgsForCall []struct { + arg1 resolver.APISet + arg2 resolver.OperatorGroupSurface + arg3 []resolver.OperatorGroupSurface + } + reconcileReturns struct { + result1 resolver.APIReconciliationResult + } + reconcileReturnsOnCall map[int]struct { + result1 resolver.APIReconciliationResult + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *FakeAPIIntersectionReconciler) Reconcile(arg1 resolver.APISet, arg2 resolver.OperatorGroupSurface, arg3 ...resolver.OperatorGroupSurface) resolver.APIReconciliationResult { + fake.reconcileMutex.Lock() + ret, specificReturn := fake.reconcileReturnsOnCall[len(fake.reconcileArgsForCall)] + fake.reconcileArgsForCall = append(fake.reconcileArgsForCall, struct { + arg1 resolver.APISet + arg2 resolver.OperatorGroupSurface + arg3 []resolver.OperatorGroupSurface + }{arg1, arg2, arg3}) + fake.recordInvocation("Reconcile", []interface{}{arg1, arg2, arg3}) + fake.reconcileMutex.Unlock() + if fake.ReconcileStub != nil { + return fake.ReconcileStub(arg1, arg2, arg3...) + } + if specificReturn { + return ret.result1 + } + fakeReturns := fake.reconcileReturns + return fakeReturns.result1 +} + +func (fake *FakeAPIIntersectionReconciler) ReconcileCallCount() int { + fake.reconcileMutex.RLock() + defer fake.reconcileMutex.RUnlock() + return len(fake.reconcileArgsForCall) +} + +func (fake *FakeAPIIntersectionReconciler) ReconcileCalls(stub func(resolver.APISet, resolver.OperatorGroupSurface, ...resolver.OperatorGroupSurface) resolver.APIReconciliationResult) { + fake.reconcileMutex.Lock() + defer fake.reconcileMutex.Unlock() + fake.ReconcileStub = stub +} + +func (fake *FakeAPIIntersectionReconciler) ReconcileArgsForCall(i int) (resolver.APISet, resolver.OperatorGroupSurface, []resolver.OperatorGroupSurface) { + fake.reconcileMutex.RLock() + defer fake.reconcileMutex.RUnlock() + argsForCall := fake.reconcileArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3 +} + +func (fake *FakeAPIIntersectionReconciler) ReconcileReturns(result1 resolver.APIReconciliationResult) { + fake.reconcileMutex.Lock() + defer fake.reconcileMutex.Unlock() + fake.ReconcileStub = nil + fake.reconcileReturns = struct { + result1 resolver.APIReconciliationResult + }{result1} +} + +func (fake *FakeAPIIntersectionReconciler) ReconcileReturnsOnCall(i int, result1 resolver.APIReconciliationResult) { + fake.reconcileMutex.Lock() + defer fake.reconcileMutex.Unlock() + fake.ReconcileStub = nil + if fake.reconcileReturnsOnCall == nil { + fake.reconcileReturnsOnCall = make(map[int]struct { + result1 resolver.APIReconciliationResult + }) + } + fake.reconcileReturnsOnCall[i] = struct { + result1 resolver.APIReconciliationResult + }{result1} +} + +func (fake *FakeAPIIntersectionReconciler) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.reconcileMutex.RLock() + defer fake.reconcileMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *FakeAPIIntersectionReconciler) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} + +var _ resolver.APIIntersectionReconciler = new(FakeAPIIntersectionReconciler) diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/fake_deployment_install_client.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/fake_deployment_install_client.go deleted file mode 100644 index 23dca08de2..0000000000 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/fake_deployment_install_client.go +++ /dev/null @@ -1,571 +0,0 @@ -// Code generated by counterfeiter. DO NOT EDIT. -package fakes - -import ( - "sync" - - "github.com/operator-framework/operator-lifecycle-manager/pkg/api/wrappers" - "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - v1beta1rbac "k8s.io/api/rbac/v1beta1" -) - -type FakeInstallStrategyDeploymentInterface struct { - CreateRoleStub func(role *v1beta1rbac.Role) (*v1beta1rbac.Role, error) - createRoleMutex sync.RWMutex - createRoleArgsForCall []struct { - role *v1beta1rbac.Role - } - createRoleReturns struct { - result1 *v1beta1rbac.Role - result2 error - } - createRoleReturnsOnCall map[int]struct { - result1 *v1beta1rbac.Role - result2 error - } - CreateRoleBindingStub func(roleBinding *v1beta1rbac.RoleBinding) (*v1beta1rbac.RoleBinding, error) - createRoleBindingMutex sync.RWMutex - createRoleBindingArgsForCall []struct { - roleBinding *v1beta1rbac.RoleBinding - } - createRoleBindingReturns struct { - result1 *v1beta1rbac.RoleBinding - result2 error - } - createRoleBindingReturnsOnCall map[int]struct { - result1 *v1beta1rbac.RoleBinding - result2 error - } - EnsureServiceAccountStub func(serviceAccount *corev1.ServiceAccount, owner ownerutil.Owner) (*corev1.ServiceAccount, error) - ensureServiceAccountMutex sync.RWMutex - ensureServiceAccountArgsForCall []struct { - serviceAccount *corev1.ServiceAccount - owner ownerutil.Owner - } - ensureServiceAccountReturns struct { - result1 *corev1.ServiceAccount - result2 error - } - ensureServiceAccountReturnsOnCall map[int]struct { - result1 *corev1.ServiceAccount - result2 error - } - CreateDeploymentStub func(deployment *appsv1.Deployment) (*appsv1.Deployment, error) - createDeploymentMutex sync.RWMutex - createDeploymentArgsForCall []struct { - deployment *appsv1.Deployment - } - createDeploymentReturns struct { - result1 *appsv1.Deployment - result2 error - } - createDeploymentReturnsOnCall map[int]struct { - result1 *appsv1.Deployment - result2 error - } - CreateOrUpdateDeploymentStub func(deployment *appsv1.Deployment) (*appsv1.Deployment, error) - createOrUpdateDeploymentMutex sync.RWMutex - createOrUpdateDeploymentArgsForCall []struct { - deployment *appsv1.Deployment - } - createOrUpdateDeploymentReturns struct { - result1 *appsv1.Deployment - result2 error - } - createOrUpdateDeploymentReturnsOnCall map[int]struct { - result1 *appsv1.Deployment - result2 error - } - DeleteDeploymentStub func(name string) error - deleteDeploymentMutex sync.RWMutex - deleteDeploymentArgsForCall []struct { - name string - } - deleteDeploymentReturns struct { - result1 error - } - deleteDeploymentReturnsOnCall map[int]struct { - result1 error - } - GetServiceAccountByNameStub func(serviceAccountName string) (*corev1.ServiceAccount, error) - getServiceAccountByNameMutex sync.RWMutex - getServiceAccountByNameArgsForCall []struct { - serviceAccountName string - } - getServiceAccountByNameReturns struct { - result1 *corev1.ServiceAccount - result2 error - } - getServiceAccountByNameReturnsOnCall map[int]struct { - result1 *corev1.ServiceAccount - result2 error - } - FindAnyDeploymentsMatchingNamesStub func(depNames []string) ([]*appsv1.Deployment, error) - findAnyDeploymentsMatchingNamesMutex sync.RWMutex - findAnyDeploymentsMatchingNamesArgsForCall []struct { - depNames []string - } - findAnyDeploymentsMatchingNamesReturns struct { - result1 []*appsv1.Deployment - result2 error - } - findAnyDeploymentsMatchingNamesReturnsOnCall map[int]struct { - result1 []*appsv1.Deployment - result2 error - } - invocations map[string][][]interface{} - invocationsMutex sync.RWMutex -} - -func (fake *FakeInstallStrategyDeploymentInterface) CreateRole(role *v1beta1rbac.Role) (*v1beta1rbac.Role, error) { - fake.createRoleMutex.Lock() - ret, specificReturn := fake.createRoleReturnsOnCall[len(fake.createRoleArgsForCall)] - fake.createRoleArgsForCall = append(fake.createRoleArgsForCall, struct { - role *v1beta1rbac.Role - }{role}) - fake.recordInvocation("CreateRole", []interface{}{role}) - fake.createRoleMutex.Unlock() - if fake.CreateRoleStub != nil { - return fake.CreateRoleStub(role) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fake.createRoleReturns.result1, fake.createRoleReturns.result2 -} - -func (fake *FakeInstallStrategyDeploymentInterface) CreateRoleCallCount() int { - fake.createRoleMutex.RLock() - defer fake.createRoleMutex.RUnlock() - return len(fake.createRoleArgsForCall) -} - -func (fake *FakeInstallStrategyDeploymentInterface) CreateRoleArgsForCall(i int) *v1beta1rbac.Role { - fake.createRoleMutex.RLock() - defer fake.createRoleMutex.RUnlock() - return fake.createRoleArgsForCall[i].role -} - -func (fake *FakeInstallStrategyDeploymentInterface) CreateRoleReturns(result1 *v1beta1rbac.Role, result2 error) { - fake.CreateRoleStub = nil - fake.createRoleReturns = struct { - result1 *v1beta1rbac.Role - result2 error - }{result1, result2} -} - -func (fake *FakeInstallStrategyDeploymentInterface) CreateRoleReturnsOnCall(i int, result1 *v1beta1rbac.Role, result2 error) { - fake.CreateRoleStub = nil - if fake.createRoleReturnsOnCall == nil { - fake.createRoleReturnsOnCall = make(map[int]struct { - result1 *v1beta1rbac.Role - result2 error - }) - } - fake.createRoleReturnsOnCall[i] = struct { - result1 *v1beta1rbac.Role - result2 error - }{result1, result2} -} - -func (fake *FakeInstallStrategyDeploymentInterface) CreateRoleBinding(roleBinding *v1beta1rbac.RoleBinding) (*v1beta1rbac.RoleBinding, error) { - fake.createRoleBindingMutex.Lock() - ret, specificReturn := fake.createRoleBindingReturnsOnCall[len(fake.createRoleBindingArgsForCall)] - fake.createRoleBindingArgsForCall = append(fake.createRoleBindingArgsForCall, struct { - roleBinding *v1beta1rbac.RoleBinding - }{roleBinding}) - fake.recordInvocation("CreateRoleBinding", []interface{}{roleBinding}) - fake.createRoleBindingMutex.Unlock() - if fake.CreateRoleBindingStub != nil { - return fake.CreateRoleBindingStub(roleBinding) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fake.createRoleBindingReturns.result1, fake.createRoleBindingReturns.result2 -} - -func (fake *FakeInstallStrategyDeploymentInterface) CreateRoleBindingCallCount() int { - fake.createRoleBindingMutex.RLock() - defer fake.createRoleBindingMutex.RUnlock() - return len(fake.createRoleBindingArgsForCall) -} - -func (fake *FakeInstallStrategyDeploymentInterface) CreateRoleBindingArgsForCall(i int) *v1beta1rbac.RoleBinding { - fake.createRoleBindingMutex.RLock() - defer fake.createRoleBindingMutex.RUnlock() - return fake.createRoleBindingArgsForCall[i].roleBinding -} - -func (fake *FakeInstallStrategyDeploymentInterface) CreateRoleBindingReturns(result1 *v1beta1rbac.RoleBinding, result2 error) { - fake.CreateRoleBindingStub = nil - fake.createRoleBindingReturns = struct { - result1 *v1beta1rbac.RoleBinding - result2 error - }{result1, result2} -} - -func (fake *FakeInstallStrategyDeploymentInterface) CreateRoleBindingReturnsOnCall(i int, result1 *v1beta1rbac.RoleBinding, result2 error) { - fake.CreateRoleBindingStub = nil - if fake.createRoleBindingReturnsOnCall == nil { - fake.createRoleBindingReturnsOnCall = make(map[int]struct { - result1 *v1beta1rbac.RoleBinding - result2 error - }) - } - fake.createRoleBindingReturnsOnCall[i] = struct { - result1 *v1beta1rbac.RoleBinding - result2 error - }{result1, result2} -} - -func (fake *FakeInstallStrategyDeploymentInterface) EnsureServiceAccount(serviceAccount *corev1.ServiceAccount, owner ownerutil.Owner) (*corev1.ServiceAccount, error) { - fake.ensureServiceAccountMutex.Lock() - ret, specificReturn := fake.ensureServiceAccountReturnsOnCall[len(fake.ensureServiceAccountArgsForCall)] - fake.ensureServiceAccountArgsForCall = append(fake.ensureServiceAccountArgsForCall, struct { - serviceAccount *corev1.ServiceAccount - owner ownerutil.Owner - }{serviceAccount, owner}) - fake.recordInvocation("EnsureServiceAccount", []interface{}{serviceAccount, owner}) - fake.ensureServiceAccountMutex.Unlock() - if fake.EnsureServiceAccountStub != nil { - return fake.EnsureServiceAccountStub(serviceAccount, owner) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fake.ensureServiceAccountReturns.result1, fake.ensureServiceAccountReturns.result2 -} - -func (fake *FakeInstallStrategyDeploymentInterface) EnsureServiceAccountCallCount() int { - fake.ensureServiceAccountMutex.RLock() - defer fake.ensureServiceAccountMutex.RUnlock() - return len(fake.ensureServiceAccountArgsForCall) -} - -func (fake *FakeInstallStrategyDeploymentInterface) EnsureServiceAccountArgsForCall(i int) (*corev1.ServiceAccount, ownerutil.Owner) { - fake.ensureServiceAccountMutex.RLock() - defer fake.ensureServiceAccountMutex.RUnlock() - return fake.ensureServiceAccountArgsForCall[i].serviceAccount, fake.ensureServiceAccountArgsForCall[i].owner -} - -func (fake *FakeInstallStrategyDeploymentInterface) EnsureServiceAccountReturns(result1 *corev1.ServiceAccount, result2 error) { - fake.EnsureServiceAccountStub = nil - fake.ensureServiceAccountReturns = struct { - result1 *corev1.ServiceAccount - result2 error - }{result1, result2} -} - -func (fake *FakeInstallStrategyDeploymentInterface) EnsureServiceAccountReturnsOnCall(i int, result1 *corev1.ServiceAccount, result2 error) { - fake.EnsureServiceAccountStub = nil - if fake.ensureServiceAccountReturnsOnCall == nil { - fake.ensureServiceAccountReturnsOnCall = make(map[int]struct { - result1 *corev1.ServiceAccount - result2 error - }) - } - fake.ensureServiceAccountReturnsOnCall[i] = struct { - result1 *corev1.ServiceAccount - result2 error - }{result1, result2} -} - -func (fake *FakeInstallStrategyDeploymentInterface) CreateDeployment(deployment *appsv1.Deployment) (*appsv1.Deployment, error) { - fake.createDeploymentMutex.Lock() - ret, specificReturn := fake.createDeploymentReturnsOnCall[len(fake.createDeploymentArgsForCall)] - fake.createDeploymentArgsForCall = append(fake.createDeploymentArgsForCall, struct { - deployment *appsv1.Deployment - }{deployment}) - fake.recordInvocation("CreateDeployment", []interface{}{deployment}) - fake.createDeploymentMutex.Unlock() - if fake.CreateDeploymentStub != nil { - return fake.CreateDeploymentStub(deployment) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fake.createDeploymentReturns.result1, fake.createDeploymentReturns.result2 -} - -func (fake *FakeInstallStrategyDeploymentInterface) CreateDeploymentCallCount() int { - fake.createDeploymentMutex.RLock() - defer fake.createDeploymentMutex.RUnlock() - return len(fake.createDeploymentArgsForCall) -} - -func (fake *FakeInstallStrategyDeploymentInterface) CreateDeploymentArgsForCall(i int) *appsv1.Deployment { - fake.createDeploymentMutex.RLock() - defer fake.createDeploymentMutex.RUnlock() - return fake.createDeploymentArgsForCall[i].deployment -} - -func (fake *FakeInstallStrategyDeploymentInterface) CreateDeploymentReturns(result1 *appsv1.Deployment, result2 error) { - fake.CreateDeploymentStub = nil - fake.createDeploymentReturns = struct { - result1 *appsv1.Deployment - result2 error - }{result1, result2} -} - -func (fake *FakeInstallStrategyDeploymentInterface) CreateDeploymentReturnsOnCall(i int, result1 *appsv1.Deployment, result2 error) { - fake.CreateDeploymentStub = nil - if fake.createDeploymentReturnsOnCall == nil { - fake.createDeploymentReturnsOnCall = make(map[int]struct { - result1 *appsv1.Deployment - result2 error - }) - } - fake.createDeploymentReturnsOnCall[i] = struct { - result1 *appsv1.Deployment - result2 error - }{result1, result2} -} - -func (fake *FakeInstallStrategyDeploymentInterface) CreateOrUpdateDeployment(deployment *appsv1.Deployment) (*appsv1.Deployment, error) { - fake.createOrUpdateDeploymentMutex.Lock() - ret, specificReturn := fake.createOrUpdateDeploymentReturnsOnCall[len(fake.createOrUpdateDeploymentArgsForCall)] - fake.createOrUpdateDeploymentArgsForCall = append(fake.createOrUpdateDeploymentArgsForCall, struct { - deployment *appsv1.Deployment - }{deployment}) - fake.recordInvocation("CreateOrUpdateDeployment", []interface{}{deployment}) - fake.createOrUpdateDeploymentMutex.Unlock() - if fake.CreateOrUpdateDeploymentStub != nil { - return fake.CreateOrUpdateDeploymentStub(deployment) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fake.createOrUpdateDeploymentReturns.result1, fake.createOrUpdateDeploymentReturns.result2 -} - -func (fake *FakeInstallStrategyDeploymentInterface) CreateOrUpdateDeploymentCallCount() int { - fake.createOrUpdateDeploymentMutex.RLock() - defer fake.createOrUpdateDeploymentMutex.RUnlock() - return len(fake.createOrUpdateDeploymentArgsForCall) -} - -func (fake *FakeInstallStrategyDeploymentInterface) CreateOrUpdateDeploymentArgsForCall(i int) *appsv1.Deployment { - fake.createOrUpdateDeploymentMutex.RLock() - defer fake.createOrUpdateDeploymentMutex.RUnlock() - return fake.createOrUpdateDeploymentArgsForCall[i].deployment -} - -func (fake *FakeInstallStrategyDeploymentInterface) CreateOrUpdateDeploymentReturns(result1 *appsv1.Deployment, result2 error) { - fake.CreateOrUpdateDeploymentStub = nil - fake.createOrUpdateDeploymentReturns = struct { - result1 *appsv1.Deployment - result2 error - }{result1, result2} -} - -func (fake *FakeInstallStrategyDeploymentInterface) CreateOrUpdateDeploymentReturnsOnCall(i int, result1 *appsv1.Deployment, result2 error) { - fake.CreateOrUpdateDeploymentStub = nil - if fake.createOrUpdateDeploymentReturnsOnCall == nil { - fake.createOrUpdateDeploymentReturnsOnCall = make(map[int]struct { - result1 *appsv1.Deployment - result2 error - }) - } - fake.createOrUpdateDeploymentReturnsOnCall[i] = struct { - result1 *appsv1.Deployment - result2 error - }{result1, result2} -} - -func (fake *FakeInstallStrategyDeploymentInterface) DeleteDeployment(name string) error { - fake.deleteDeploymentMutex.Lock() - ret, specificReturn := fake.deleteDeploymentReturnsOnCall[len(fake.deleteDeploymentArgsForCall)] - fake.deleteDeploymentArgsForCall = append(fake.deleteDeploymentArgsForCall, struct { - name string - }{name}) - fake.recordInvocation("DeleteDeployment", []interface{}{name}) - fake.deleteDeploymentMutex.Unlock() - if fake.DeleteDeploymentStub != nil { - return fake.DeleteDeploymentStub(name) - } - if specificReturn { - return ret.result1 - } - return fake.deleteDeploymentReturns.result1 -} - -func (fake *FakeInstallStrategyDeploymentInterface) DeleteDeploymentCallCount() int { - fake.deleteDeploymentMutex.RLock() - defer fake.deleteDeploymentMutex.RUnlock() - return len(fake.deleteDeploymentArgsForCall) -} - -func (fake *FakeInstallStrategyDeploymentInterface) DeleteDeploymentArgsForCall(i int) string { - fake.deleteDeploymentMutex.RLock() - defer fake.deleteDeploymentMutex.RUnlock() - return fake.deleteDeploymentArgsForCall[i].name -} - -func (fake *FakeInstallStrategyDeploymentInterface) DeleteDeploymentReturns(result1 error) { - fake.DeleteDeploymentStub = nil - fake.deleteDeploymentReturns = struct { - result1 error - }{result1} -} - -func (fake *FakeInstallStrategyDeploymentInterface) DeleteDeploymentReturnsOnCall(i int, result1 error) { - fake.DeleteDeploymentStub = nil - if fake.deleteDeploymentReturnsOnCall == nil { - fake.deleteDeploymentReturnsOnCall = make(map[int]struct { - result1 error - }) - } - fake.deleteDeploymentReturnsOnCall[i] = struct { - result1 error - }{result1} -} - -func (fake *FakeInstallStrategyDeploymentInterface) GetServiceAccountByName(serviceAccountName string) (*corev1.ServiceAccount, error) { - fake.getServiceAccountByNameMutex.Lock() - ret, specificReturn := fake.getServiceAccountByNameReturnsOnCall[len(fake.getServiceAccountByNameArgsForCall)] - fake.getServiceAccountByNameArgsForCall = append(fake.getServiceAccountByNameArgsForCall, struct { - serviceAccountName string - }{serviceAccountName}) - fake.recordInvocation("GetServiceAccountByName", []interface{}{serviceAccountName}) - fake.getServiceAccountByNameMutex.Unlock() - if fake.GetServiceAccountByNameStub != nil { - return fake.GetServiceAccountByNameStub(serviceAccountName) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fake.getServiceAccountByNameReturns.result1, fake.getServiceAccountByNameReturns.result2 -} - -func (fake *FakeInstallStrategyDeploymentInterface) GetServiceAccountByNameCallCount() int { - fake.getServiceAccountByNameMutex.RLock() - defer fake.getServiceAccountByNameMutex.RUnlock() - return len(fake.getServiceAccountByNameArgsForCall) -} - -func (fake *FakeInstallStrategyDeploymentInterface) GetServiceAccountByNameArgsForCall(i int) string { - fake.getServiceAccountByNameMutex.RLock() - defer fake.getServiceAccountByNameMutex.RUnlock() - return fake.getServiceAccountByNameArgsForCall[i].serviceAccountName -} - -func (fake *FakeInstallStrategyDeploymentInterface) GetServiceAccountByNameReturns(result1 *corev1.ServiceAccount, result2 error) { - fake.GetServiceAccountByNameStub = nil - fake.getServiceAccountByNameReturns = struct { - result1 *corev1.ServiceAccount - result2 error - }{result1, result2} -} - -func (fake *FakeInstallStrategyDeploymentInterface) GetServiceAccountByNameReturnsOnCall(i int, result1 *corev1.ServiceAccount, result2 error) { - fake.GetServiceAccountByNameStub = nil - if fake.getServiceAccountByNameReturnsOnCall == nil { - fake.getServiceAccountByNameReturnsOnCall = make(map[int]struct { - result1 *corev1.ServiceAccount - result2 error - }) - } - fake.getServiceAccountByNameReturnsOnCall[i] = struct { - result1 *corev1.ServiceAccount - result2 error - }{result1, result2} -} - -func (fake *FakeInstallStrategyDeploymentInterface) FindAnyDeploymentsMatchingNames(depNames []string) ([]*appsv1.Deployment, error) { - var depNamesCopy []string - if depNames != nil { - depNamesCopy = make([]string, len(depNames)) - copy(depNamesCopy, depNames) - } - fake.findAnyDeploymentsMatchingNamesMutex.Lock() - ret, specificReturn := fake.findAnyDeploymentsMatchingNamesReturnsOnCall[len(fake.findAnyDeploymentsMatchingNamesArgsForCall)] - fake.findAnyDeploymentsMatchingNamesArgsForCall = append(fake.findAnyDeploymentsMatchingNamesArgsForCall, struct { - depNames []string - }{depNamesCopy}) - fake.recordInvocation("FindAnyDeploymentsMatchingNames", []interface{}{depNamesCopy}) - fake.findAnyDeploymentsMatchingNamesMutex.Unlock() - if fake.FindAnyDeploymentsMatchingNamesStub != nil { - return fake.FindAnyDeploymentsMatchingNamesStub(depNames) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fake.findAnyDeploymentsMatchingNamesReturns.result1, fake.findAnyDeploymentsMatchingNamesReturns.result2 -} - -func (fake *FakeInstallStrategyDeploymentInterface) FindAnyDeploymentsMatchingNamesCallCount() int { - fake.findAnyDeploymentsMatchingNamesMutex.RLock() - defer fake.findAnyDeploymentsMatchingNamesMutex.RUnlock() - return len(fake.findAnyDeploymentsMatchingNamesArgsForCall) -} - -func (fake *FakeInstallStrategyDeploymentInterface) FindAnyDeploymentsMatchingNamesArgsForCall(i int) []string { - fake.findAnyDeploymentsMatchingNamesMutex.RLock() - defer fake.findAnyDeploymentsMatchingNamesMutex.RUnlock() - return fake.findAnyDeploymentsMatchingNamesArgsForCall[i].depNames -} - -func (fake *FakeInstallStrategyDeploymentInterface) FindAnyDeploymentsMatchingNamesReturns(result1 []*appsv1.Deployment, result2 error) { - fake.FindAnyDeploymentsMatchingNamesStub = nil - fake.findAnyDeploymentsMatchingNamesReturns = struct { - result1 []*appsv1.Deployment - result2 error - }{result1, result2} -} - -func (fake *FakeInstallStrategyDeploymentInterface) FindAnyDeploymentsMatchingNamesReturnsOnCall(i int, result1 []*appsv1.Deployment, result2 error) { - fake.FindAnyDeploymentsMatchingNamesStub = nil - if fake.findAnyDeploymentsMatchingNamesReturnsOnCall == nil { - fake.findAnyDeploymentsMatchingNamesReturnsOnCall = make(map[int]struct { - result1 []*appsv1.Deployment - result2 error - }) - } - fake.findAnyDeploymentsMatchingNamesReturnsOnCall[i] = struct { - result1 []*appsv1.Deployment - result2 error - }{result1, result2} -} - -func (fake *FakeInstallStrategyDeploymentInterface) Invocations() map[string][][]interface{} { - fake.invocationsMutex.RLock() - defer fake.invocationsMutex.RUnlock() - fake.createRoleMutex.RLock() - defer fake.createRoleMutex.RUnlock() - fake.createRoleBindingMutex.RLock() - defer fake.createRoleBindingMutex.RUnlock() - fake.ensureServiceAccountMutex.RLock() - defer fake.ensureServiceAccountMutex.RUnlock() - fake.createDeploymentMutex.RLock() - defer fake.createDeploymentMutex.RUnlock() - fake.createOrUpdateDeploymentMutex.RLock() - defer fake.createOrUpdateDeploymentMutex.RUnlock() - fake.deleteDeploymentMutex.RLock() - defer fake.deleteDeploymentMutex.RUnlock() - fake.getServiceAccountByNameMutex.RLock() - defer fake.getServiceAccountByNameMutex.RUnlock() - fake.findAnyDeploymentsMatchingNamesMutex.RLock() - defer fake.findAnyDeploymentsMatchingNamesMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} - for key, value := range fake.invocations { - copiedInvocations[key] = value - } - return copiedInvocations -} - -func (fake *FakeInstallStrategyDeploymentInterface) recordInvocation(key string, args []interface{}) { - fake.invocationsMutex.Lock() - defer fake.invocationsMutex.Unlock() - if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} - } - if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} - } - fake.invocations[key] = append(fake.invocations[key], args) -} - -var _ wrappers.InstallStrategyDeploymentInterface = new(FakeInstallStrategyDeploymentInterface) diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/fake_reconciler.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/fake_reconciler.go new file mode 100644 index 0000000000..d8c890723c --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/fake_reconciler.go @@ -0,0 +1,111 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package fakes + +import ( + sync "sync" + + v1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + reconciler "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/reconciler" +) + +type FakeRegistryReconciler struct { + EnsureRegistryServerStub func(*v1alpha1.CatalogSource) error + ensureRegistryServerMutex sync.RWMutex + ensureRegistryServerArgsForCall []struct { + arg1 *v1alpha1.CatalogSource + } + ensureRegistryServerReturns struct { + result1 error + } + ensureRegistryServerReturnsOnCall map[int]struct { + result1 error + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *FakeRegistryReconciler) EnsureRegistryServer(arg1 *v1alpha1.CatalogSource) error { + fake.ensureRegistryServerMutex.Lock() + ret, specificReturn := fake.ensureRegistryServerReturnsOnCall[len(fake.ensureRegistryServerArgsForCall)] + fake.ensureRegistryServerArgsForCall = append(fake.ensureRegistryServerArgsForCall, struct { + arg1 *v1alpha1.CatalogSource + }{arg1}) + fake.recordInvocation("EnsureRegistryServer", []interface{}{arg1}) + fake.ensureRegistryServerMutex.Unlock() + if fake.EnsureRegistryServerStub != nil { + return fake.EnsureRegistryServerStub(arg1) + } + if specificReturn { + return ret.result1 + } + fakeReturns := fake.ensureRegistryServerReturns + return fakeReturns.result1 +} + +func (fake *FakeRegistryReconciler) EnsureRegistryServerCallCount() int { + fake.ensureRegistryServerMutex.RLock() + defer fake.ensureRegistryServerMutex.RUnlock() + return len(fake.ensureRegistryServerArgsForCall) +} + +func (fake *FakeRegistryReconciler) EnsureRegistryServerCalls(stub func(*v1alpha1.CatalogSource) error) { + fake.ensureRegistryServerMutex.Lock() + defer fake.ensureRegistryServerMutex.Unlock() + fake.EnsureRegistryServerStub = stub +} + +func (fake *FakeRegistryReconciler) EnsureRegistryServerArgsForCall(i int) *v1alpha1.CatalogSource { + fake.ensureRegistryServerMutex.RLock() + defer fake.ensureRegistryServerMutex.RUnlock() + argsForCall := fake.ensureRegistryServerArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FakeRegistryReconciler) EnsureRegistryServerReturns(result1 error) { + fake.ensureRegistryServerMutex.Lock() + defer fake.ensureRegistryServerMutex.Unlock() + fake.EnsureRegistryServerStub = nil + fake.ensureRegistryServerReturns = struct { + result1 error + }{result1} +} + +func (fake *FakeRegistryReconciler) EnsureRegistryServerReturnsOnCall(i int, result1 error) { + fake.ensureRegistryServerMutex.Lock() + defer fake.ensureRegistryServerMutex.Unlock() + fake.EnsureRegistryServerStub = nil + if fake.ensureRegistryServerReturnsOnCall == nil { + fake.ensureRegistryServerReturnsOnCall = make(map[int]struct { + result1 error + }) + } + fake.ensureRegistryServerReturnsOnCall[i] = struct { + result1 error + }{result1} +} + +func (fake *FakeRegistryReconciler) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.ensureRegistryServerMutex.RLock() + defer fake.ensureRegistryServerMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *FakeRegistryReconciler) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} + +var _ reconciler.RegistryReconciler = new(FakeRegistryReconciler) diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/fake_reconciler_reconciler.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/fake_reconciler_reconciler.go new file mode 100644 index 0000000000..3069786dd3 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/fake_reconciler_reconciler.go @@ -0,0 +1,111 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package fakes + +import ( + sync "sync" + + v1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + reconciler "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/reconciler" +) + +type FakeReconcilerFactory struct { + ReconcilerForSourceStub func(*v1alpha1.CatalogSource) reconciler.RegistryReconciler + reconcilerForSourceMutex sync.RWMutex + reconcilerForSourceArgsForCall []struct { + arg1 *v1alpha1.CatalogSource + } + reconcilerForSourceReturns struct { + result1 reconciler.RegistryReconciler + } + reconcilerForSourceReturnsOnCall map[int]struct { + result1 reconciler.RegistryReconciler + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *FakeReconcilerFactory) ReconcilerForSource(arg1 *v1alpha1.CatalogSource) reconciler.RegistryReconciler { + fake.reconcilerForSourceMutex.Lock() + ret, specificReturn := fake.reconcilerForSourceReturnsOnCall[len(fake.reconcilerForSourceArgsForCall)] + fake.reconcilerForSourceArgsForCall = append(fake.reconcilerForSourceArgsForCall, struct { + arg1 *v1alpha1.CatalogSource + }{arg1}) + fake.recordInvocation("ReconcilerForSource", []interface{}{arg1}) + fake.reconcilerForSourceMutex.Unlock() + if fake.ReconcilerForSourceStub != nil { + return fake.ReconcilerForSourceStub(arg1) + } + if specificReturn { + return ret.result1 + } + fakeReturns := fake.reconcilerForSourceReturns + return fakeReturns.result1 +} + +func (fake *FakeReconcilerFactory) ReconcilerForSourceCallCount() int { + fake.reconcilerForSourceMutex.RLock() + defer fake.reconcilerForSourceMutex.RUnlock() + return len(fake.reconcilerForSourceArgsForCall) +} + +func (fake *FakeReconcilerFactory) ReconcilerForSourceCalls(stub func(*v1alpha1.CatalogSource) reconciler.RegistryReconciler) { + fake.reconcilerForSourceMutex.Lock() + defer fake.reconcilerForSourceMutex.Unlock() + fake.ReconcilerForSourceStub = stub +} + +func (fake *FakeReconcilerFactory) ReconcilerForSourceArgsForCall(i int) *v1alpha1.CatalogSource { + fake.reconcilerForSourceMutex.RLock() + defer fake.reconcilerForSourceMutex.RUnlock() + argsForCall := fake.reconcilerForSourceArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FakeReconcilerFactory) ReconcilerForSourceReturns(result1 reconciler.RegistryReconciler) { + fake.reconcilerForSourceMutex.Lock() + defer fake.reconcilerForSourceMutex.Unlock() + fake.ReconcilerForSourceStub = nil + fake.reconcilerForSourceReturns = struct { + result1 reconciler.RegistryReconciler + }{result1} +} + +func (fake *FakeReconcilerFactory) ReconcilerForSourceReturnsOnCall(i int, result1 reconciler.RegistryReconciler) { + fake.reconcilerForSourceMutex.Lock() + defer fake.reconcilerForSourceMutex.Unlock() + fake.ReconcilerForSourceStub = nil + if fake.reconcilerForSourceReturnsOnCall == nil { + fake.reconcilerForSourceReturnsOnCall = make(map[int]struct { + result1 reconciler.RegistryReconciler + }) + } + fake.reconcilerForSourceReturnsOnCall[i] = struct { + result1 reconciler.RegistryReconciler + }{result1} +} + +func (fake *FakeReconcilerFactory) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.reconcilerForSourceMutex.RLock() + defer fake.reconcilerForSourceMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *FakeReconcilerFactory) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} + +var _ reconciler.ReconcilerFactory = new(FakeReconcilerFactory) diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/fake_registry_source.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/fake_registry_source.go deleted file mode 100644 index 28c13439c2..0000000000 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/fake_registry_source.go +++ /dev/null @@ -1,548 +0,0 @@ -// Code generated by counterfeiter. DO NOT EDIT. -package fakes - -import ( - "sync" - - "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" - "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry" - "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" -) - -type FakeSource struct { - FindCSVForPackageNameUnderChannelStub func(packageName string, channelName string) (*v1alpha1.ClusterServiceVersion, error) - findCSVForPackageNameUnderChannelMutex sync.RWMutex - findCSVForPackageNameUnderChannelArgsForCall []struct { - packageName string - channelName string - } - findCSVForPackageNameUnderChannelReturns struct { - result1 *v1alpha1.ClusterServiceVersion - result2 error - } - findCSVForPackageNameUnderChannelReturnsOnCall map[int]struct { - result1 *v1alpha1.ClusterServiceVersion - result2 error - } - FindReplacementCSVForPackageNameUnderChannelStub func(packageName string, channelName string, csvName string) (*v1alpha1.ClusterServiceVersion, error) - findReplacementCSVForPackageNameUnderChannelMutex sync.RWMutex - findReplacementCSVForPackageNameUnderChannelArgsForCall []struct { - packageName string - channelName string - csvName string - } - findReplacementCSVForPackageNameUnderChannelReturns struct { - result1 *v1alpha1.ClusterServiceVersion - result2 error - } - findReplacementCSVForPackageNameUnderChannelReturnsOnCall map[int]struct { - result1 *v1alpha1.ClusterServiceVersion - result2 error - } - AllPackagesStub func() map[string]registry.PackageManifest - allPackagesMutex sync.RWMutex - allPackagesArgsForCall []struct{} - allPackagesReturns struct { - result1 map[string]registry.PackageManifest - } - allPackagesReturnsOnCall map[int]struct { - result1 map[string]registry.PackageManifest - } - FindReplacementCSVForNameStub func(name string) (*v1alpha1.ClusterServiceVersion, error) - findReplacementCSVForNameMutex sync.RWMutex - findReplacementCSVForNameArgsForCall []struct { - name string - } - findReplacementCSVForNameReturns struct { - result1 *v1alpha1.ClusterServiceVersion - result2 error - } - findReplacementCSVForNameReturnsOnCall map[int]struct { - result1 *v1alpha1.ClusterServiceVersion - result2 error - } - FindCSVByNameStub func(name string) (*v1alpha1.ClusterServiceVersion, error) - findCSVByNameMutex sync.RWMutex - findCSVByNameArgsForCall []struct { - name string - } - findCSVByNameReturns struct { - result1 *v1alpha1.ClusterServiceVersion - result2 error - } - findCSVByNameReturnsOnCall map[int]struct { - result1 *v1alpha1.ClusterServiceVersion - result2 error - } - ListServicesStub func() ([]v1alpha1.ClusterServiceVersion, error) - listServicesMutex sync.RWMutex - listServicesArgsForCall []struct{} - listServicesReturns struct { - result1 []v1alpha1.ClusterServiceVersion - result2 error - } - listServicesReturnsOnCall map[int]struct { - result1 []v1alpha1.ClusterServiceVersion - result2 error - } - FindCRDByKeyStub func(key registry.CRDKey) (*v1beta1.CustomResourceDefinition, error) - findCRDByKeyMutex sync.RWMutex - findCRDByKeyArgsForCall []struct { - key registry.CRDKey - } - findCRDByKeyReturns struct { - result1 *v1beta1.CustomResourceDefinition - result2 error - } - findCRDByKeyReturnsOnCall map[int]struct { - result1 *v1beta1.CustomResourceDefinition - result2 error - } - ListLatestCSVsForCRDStub func(key registry.CRDKey) ([]registry.CSVAndChannelInfo, error) - listLatestCSVsForCRDMutex sync.RWMutex - listLatestCSVsForCRDArgsForCall []struct { - key registry.CRDKey - } - listLatestCSVsForCRDReturns struct { - result1 []registry.CSVAndChannelInfo - result2 error - } - listLatestCSVsForCRDReturnsOnCall map[int]struct { - result1 []registry.CSVAndChannelInfo - result2 error - } - invocations map[string][][]interface{} - invocationsMutex sync.RWMutex -} - -func (fake *FakeSource) FindCSVForPackageNameUnderChannel(packageName string, channelName string) (*v1alpha1.ClusterServiceVersion, error) { - fake.findCSVForPackageNameUnderChannelMutex.Lock() - ret, specificReturn := fake.findCSVForPackageNameUnderChannelReturnsOnCall[len(fake.findCSVForPackageNameUnderChannelArgsForCall)] - fake.findCSVForPackageNameUnderChannelArgsForCall = append(fake.findCSVForPackageNameUnderChannelArgsForCall, struct { - packageName string - channelName string - }{packageName, channelName}) - fake.recordInvocation("FindCSVForPackageNameUnderChannel", []interface{}{packageName, channelName}) - fake.findCSVForPackageNameUnderChannelMutex.Unlock() - if fake.FindCSVForPackageNameUnderChannelStub != nil { - return fake.FindCSVForPackageNameUnderChannelStub(packageName, channelName) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fake.findCSVForPackageNameUnderChannelReturns.result1, fake.findCSVForPackageNameUnderChannelReturns.result2 -} - -func (fake *FakeSource) FindCSVForPackageNameUnderChannelCallCount() int { - fake.findCSVForPackageNameUnderChannelMutex.RLock() - defer fake.findCSVForPackageNameUnderChannelMutex.RUnlock() - return len(fake.findCSVForPackageNameUnderChannelArgsForCall) -} - -func (fake *FakeSource) FindCSVForPackageNameUnderChannelArgsForCall(i int) (string, string) { - fake.findCSVForPackageNameUnderChannelMutex.RLock() - defer fake.findCSVForPackageNameUnderChannelMutex.RUnlock() - return fake.findCSVForPackageNameUnderChannelArgsForCall[i].packageName, fake.findCSVForPackageNameUnderChannelArgsForCall[i].channelName -} - -func (fake *FakeSource) FindCSVForPackageNameUnderChannelReturns(result1 *v1alpha1.ClusterServiceVersion, result2 error) { - fake.FindCSVForPackageNameUnderChannelStub = nil - fake.findCSVForPackageNameUnderChannelReturns = struct { - result1 *v1alpha1.ClusterServiceVersion - result2 error - }{result1, result2} -} - -func (fake *FakeSource) FindCSVForPackageNameUnderChannelReturnsOnCall(i int, result1 *v1alpha1.ClusterServiceVersion, result2 error) { - fake.FindCSVForPackageNameUnderChannelStub = nil - if fake.findCSVForPackageNameUnderChannelReturnsOnCall == nil { - fake.findCSVForPackageNameUnderChannelReturnsOnCall = make(map[int]struct { - result1 *v1alpha1.ClusterServiceVersion - result2 error - }) - } - fake.findCSVForPackageNameUnderChannelReturnsOnCall[i] = struct { - result1 *v1alpha1.ClusterServiceVersion - result2 error - }{result1, result2} -} - -func (fake *FakeSource) FindReplacementCSVForPackageNameUnderChannel(packageName string, channelName string, csvName string) (*v1alpha1.ClusterServiceVersion, error) { - fake.findReplacementCSVForPackageNameUnderChannelMutex.Lock() - ret, specificReturn := fake.findReplacementCSVForPackageNameUnderChannelReturnsOnCall[len(fake.findReplacementCSVForPackageNameUnderChannelArgsForCall)] - fake.findReplacementCSVForPackageNameUnderChannelArgsForCall = append(fake.findReplacementCSVForPackageNameUnderChannelArgsForCall, struct { - packageName string - channelName string - csvName string - }{packageName, channelName, csvName}) - fake.recordInvocation("FindReplacementCSVForPackageNameUnderChannel", []interface{}{packageName, channelName, csvName}) - fake.findReplacementCSVForPackageNameUnderChannelMutex.Unlock() - if fake.FindReplacementCSVForPackageNameUnderChannelStub != nil { - return fake.FindReplacementCSVForPackageNameUnderChannelStub(packageName, channelName, csvName) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fake.findReplacementCSVForPackageNameUnderChannelReturns.result1, fake.findReplacementCSVForPackageNameUnderChannelReturns.result2 -} - -func (fake *FakeSource) FindReplacementCSVForPackageNameUnderChannelCallCount() int { - fake.findReplacementCSVForPackageNameUnderChannelMutex.RLock() - defer fake.findReplacementCSVForPackageNameUnderChannelMutex.RUnlock() - return len(fake.findReplacementCSVForPackageNameUnderChannelArgsForCall) -} - -func (fake *FakeSource) FindReplacementCSVForPackageNameUnderChannelArgsForCall(i int) (string, string, string) { - fake.findReplacementCSVForPackageNameUnderChannelMutex.RLock() - defer fake.findReplacementCSVForPackageNameUnderChannelMutex.RUnlock() - return fake.findReplacementCSVForPackageNameUnderChannelArgsForCall[i].packageName, fake.findReplacementCSVForPackageNameUnderChannelArgsForCall[i].channelName, fake.findReplacementCSVForPackageNameUnderChannelArgsForCall[i].csvName -} - -func (fake *FakeSource) FindReplacementCSVForPackageNameUnderChannelReturns(result1 *v1alpha1.ClusterServiceVersion, result2 error) { - fake.FindReplacementCSVForPackageNameUnderChannelStub = nil - fake.findReplacementCSVForPackageNameUnderChannelReturns = struct { - result1 *v1alpha1.ClusterServiceVersion - result2 error - }{result1, result2} -} - -func (fake *FakeSource) FindReplacementCSVForPackageNameUnderChannelReturnsOnCall(i int, result1 *v1alpha1.ClusterServiceVersion, result2 error) { - fake.FindReplacementCSVForPackageNameUnderChannelStub = nil - if fake.findReplacementCSVForPackageNameUnderChannelReturnsOnCall == nil { - fake.findReplacementCSVForPackageNameUnderChannelReturnsOnCall = make(map[int]struct { - result1 *v1alpha1.ClusterServiceVersion - result2 error - }) - } - fake.findReplacementCSVForPackageNameUnderChannelReturnsOnCall[i] = struct { - result1 *v1alpha1.ClusterServiceVersion - result2 error - }{result1, result2} -} - -func (fake *FakeSource) AllPackages() map[string]registry.PackageManifest { - fake.allPackagesMutex.Lock() - ret, specificReturn := fake.allPackagesReturnsOnCall[len(fake.allPackagesArgsForCall)] - fake.allPackagesArgsForCall = append(fake.allPackagesArgsForCall, struct{}{}) - fake.recordInvocation("AllPackages", []interface{}{}) - fake.allPackagesMutex.Unlock() - if fake.AllPackagesStub != nil { - return fake.AllPackagesStub() - } - if specificReturn { - return ret.result1 - } - return fake.allPackagesReturns.result1 -} - -func (fake *FakeSource) AllPackagesCallCount() int { - fake.allPackagesMutex.RLock() - defer fake.allPackagesMutex.RUnlock() - return len(fake.allPackagesArgsForCall) -} - -func (fake *FakeSource) AllPackagesReturns(result1 map[string]registry.PackageManifest) { - fake.AllPackagesStub = nil - fake.allPackagesReturns = struct { - result1 map[string]registry.PackageManifest - }{result1} -} - -func (fake *FakeSource) AllPackagesReturnsOnCall(i int, result1 map[string]registry.PackageManifest) { - fake.AllPackagesStub = nil - if fake.allPackagesReturnsOnCall == nil { - fake.allPackagesReturnsOnCall = make(map[int]struct { - result1 map[string]registry.PackageManifest - }) - } - fake.allPackagesReturnsOnCall[i] = struct { - result1 map[string]registry.PackageManifest - }{result1} -} - -func (fake *FakeSource) FindReplacementCSVForName(name string) (*v1alpha1.ClusterServiceVersion, error) { - fake.findReplacementCSVForNameMutex.Lock() - ret, specificReturn := fake.findReplacementCSVForNameReturnsOnCall[len(fake.findReplacementCSVForNameArgsForCall)] - fake.findReplacementCSVForNameArgsForCall = append(fake.findReplacementCSVForNameArgsForCall, struct { - name string - }{name}) - fake.recordInvocation("FindReplacementCSVForName", []interface{}{name}) - fake.findReplacementCSVForNameMutex.Unlock() - if fake.FindReplacementCSVForNameStub != nil { - return fake.FindReplacementCSVForNameStub(name) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fake.findReplacementCSVForNameReturns.result1, fake.findReplacementCSVForNameReturns.result2 -} - -func (fake *FakeSource) FindReplacementCSVForNameCallCount() int { - fake.findReplacementCSVForNameMutex.RLock() - defer fake.findReplacementCSVForNameMutex.RUnlock() - return len(fake.findReplacementCSVForNameArgsForCall) -} - -func (fake *FakeSource) FindReplacementCSVForNameArgsForCall(i int) string { - fake.findReplacementCSVForNameMutex.RLock() - defer fake.findReplacementCSVForNameMutex.RUnlock() - return fake.findReplacementCSVForNameArgsForCall[i].name -} - -func (fake *FakeSource) FindReplacementCSVForNameReturns(result1 *v1alpha1.ClusterServiceVersion, result2 error) { - fake.FindReplacementCSVForNameStub = nil - fake.findReplacementCSVForNameReturns = struct { - result1 *v1alpha1.ClusterServiceVersion - result2 error - }{result1, result2} -} - -func (fake *FakeSource) FindReplacementCSVForNameReturnsOnCall(i int, result1 *v1alpha1.ClusterServiceVersion, result2 error) { - fake.FindReplacementCSVForNameStub = nil - if fake.findReplacementCSVForNameReturnsOnCall == nil { - fake.findReplacementCSVForNameReturnsOnCall = make(map[int]struct { - result1 *v1alpha1.ClusterServiceVersion - result2 error - }) - } - fake.findReplacementCSVForNameReturnsOnCall[i] = struct { - result1 *v1alpha1.ClusterServiceVersion - result2 error - }{result1, result2} -} - -func (fake *FakeSource) FindCSVByName(name string) (*v1alpha1.ClusterServiceVersion, error) { - fake.findCSVByNameMutex.Lock() - ret, specificReturn := fake.findCSVByNameReturnsOnCall[len(fake.findCSVByNameArgsForCall)] - fake.findCSVByNameArgsForCall = append(fake.findCSVByNameArgsForCall, struct { - name string - }{name}) - fake.recordInvocation("FindCSVByName", []interface{}{name}) - fake.findCSVByNameMutex.Unlock() - if fake.FindCSVByNameStub != nil { - return fake.FindCSVByNameStub(name) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fake.findCSVByNameReturns.result1, fake.findCSVByNameReturns.result2 -} - -func (fake *FakeSource) FindCSVByNameCallCount() int { - fake.findCSVByNameMutex.RLock() - defer fake.findCSVByNameMutex.RUnlock() - return len(fake.findCSVByNameArgsForCall) -} - -func (fake *FakeSource) FindCSVByNameArgsForCall(i int) string { - fake.findCSVByNameMutex.RLock() - defer fake.findCSVByNameMutex.RUnlock() - return fake.findCSVByNameArgsForCall[i].name -} - -func (fake *FakeSource) FindCSVByNameReturns(result1 *v1alpha1.ClusterServiceVersion, result2 error) { - fake.FindCSVByNameStub = nil - fake.findCSVByNameReturns = struct { - result1 *v1alpha1.ClusterServiceVersion - result2 error - }{result1, result2} -} - -func (fake *FakeSource) FindCSVByNameReturnsOnCall(i int, result1 *v1alpha1.ClusterServiceVersion, result2 error) { - fake.FindCSVByNameStub = nil - if fake.findCSVByNameReturnsOnCall == nil { - fake.findCSVByNameReturnsOnCall = make(map[int]struct { - result1 *v1alpha1.ClusterServiceVersion - result2 error - }) - } - fake.findCSVByNameReturnsOnCall[i] = struct { - result1 *v1alpha1.ClusterServiceVersion - result2 error - }{result1, result2} -} - -func (fake *FakeSource) ListServices() ([]v1alpha1.ClusterServiceVersion, error) { - fake.listServicesMutex.Lock() - ret, specificReturn := fake.listServicesReturnsOnCall[len(fake.listServicesArgsForCall)] - fake.listServicesArgsForCall = append(fake.listServicesArgsForCall, struct{}{}) - fake.recordInvocation("ListServices", []interface{}{}) - fake.listServicesMutex.Unlock() - if fake.ListServicesStub != nil { - return fake.ListServicesStub() - } - if specificReturn { - return ret.result1, ret.result2 - } - return fake.listServicesReturns.result1, fake.listServicesReturns.result2 -} - -func (fake *FakeSource) ListServicesCallCount() int { - fake.listServicesMutex.RLock() - defer fake.listServicesMutex.RUnlock() - return len(fake.listServicesArgsForCall) -} - -func (fake *FakeSource) ListServicesReturns(result1 []v1alpha1.ClusterServiceVersion, result2 error) { - fake.ListServicesStub = nil - fake.listServicesReturns = struct { - result1 []v1alpha1.ClusterServiceVersion - result2 error - }{result1, result2} -} - -func (fake *FakeSource) ListServicesReturnsOnCall(i int, result1 []v1alpha1.ClusterServiceVersion, result2 error) { - fake.ListServicesStub = nil - if fake.listServicesReturnsOnCall == nil { - fake.listServicesReturnsOnCall = make(map[int]struct { - result1 []v1alpha1.ClusterServiceVersion - result2 error - }) - } - fake.listServicesReturnsOnCall[i] = struct { - result1 []v1alpha1.ClusterServiceVersion - result2 error - }{result1, result2} -} - -func (fake *FakeSource) FindCRDByKey(key registry.CRDKey) (*v1beta1.CustomResourceDefinition, error) { - fake.findCRDByKeyMutex.Lock() - ret, specificReturn := fake.findCRDByKeyReturnsOnCall[len(fake.findCRDByKeyArgsForCall)] - fake.findCRDByKeyArgsForCall = append(fake.findCRDByKeyArgsForCall, struct { - key registry.CRDKey - }{key}) - fake.recordInvocation("FindCRDByKey", []interface{}{key}) - fake.findCRDByKeyMutex.Unlock() - if fake.FindCRDByKeyStub != nil { - return fake.FindCRDByKeyStub(key) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fake.findCRDByKeyReturns.result1, fake.findCRDByKeyReturns.result2 -} - -func (fake *FakeSource) FindCRDByKeyCallCount() int { - fake.findCRDByKeyMutex.RLock() - defer fake.findCRDByKeyMutex.RUnlock() - return len(fake.findCRDByKeyArgsForCall) -} - -func (fake *FakeSource) FindCRDByKeyArgsForCall(i int) registry.CRDKey { - fake.findCRDByKeyMutex.RLock() - defer fake.findCRDByKeyMutex.RUnlock() - return fake.findCRDByKeyArgsForCall[i].key -} - -func (fake *FakeSource) FindCRDByKeyReturns(result1 *v1beta1.CustomResourceDefinition, result2 error) { - fake.FindCRDByKeyStub = nil - fake.findCRDByKeyReturns = struct { - result1 *v1beta1.CustomResourceDefinition - result2 error - }{result1, result2} -} - -func (fake *FakeSource) FindCRDByKeyReturnsOnCall(i int, result1 *v1beta1.CustomResourceDefinition, result2 error) { - fake.FindCRDByKeyStub = nil - if fake.findCRDByKeyReturnsOnCall == nil { - fake.findCRDByKeyReturnsOnCall = make(map[int]struct { - result1 *v1beta1.CustomResourceDefinition - result2 error - }) - } - fake.findCRDByKeyReturnsOnCall[i] = struct { - result1 *v1beta1.CustomResourceDefinition - result2 error - }{result1, result2} -} - -func (fake *FakeSource) ListLatestCSVsForCRD(key registry.CRDKey) ([]registry.CSVAndChannelInfo, error) { - fake.listLatestCSVsForCRDMutex.Lock() - ret, specificReturn := fake.listLatestCSVsForCRDReturnsOnCall[len(fake.listLatestCSVsForCRDArgsForCall)] - fake.listLatestCSVsForCRDArgsForCall = append(fake.listLatestCSVsForCRDArgsForCall, struct { - key registry.CRDKey - }{key}) - fake.recordInvocation("ListLatestCSVsForCRD", []interface{}{key}) - fake.listLatestCSVsForCRDMutex.Unlock() - if fake.ListLatestCSVsForCRDStub != nil { - return fake.ListLatestCSVsForCRDStub(key) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fake.listLatestCSVsForCRDReturns.result1, fake.listLatestCSVsForCRDReturns.result2 -} - -func (fake *FakeSource) ListLatestCSVsForCRDCallCount() int { - fake.listLatestCSVsForCRDMutex.RLock() - defer fake.listLatestCSVsForCRDMutex.RUnlock() - return len(fake.listLatestCSVsForCRDArgsForCall) -} - -func (fake *FakeSource) ListLatestCSVsForCRDArgsForCall(i int) registry.CRDKey { - fake.listLatestCSVsForCRDMutex.RLock() - defer fake.listLatestCSVsForCRDMutex.RUnlock() - return fake.listLatestCSVsForCRDArgsForCall[i].key -} - -func (fake *FakeSource) ListLatestCSVsForCRDReturns(result1 []registry.CSVAndChannelInfo, result2 error) { - fake.ListLatestCSVsForCRDStub = nil - fake.listLatestCSVsForCRDReturns = struct { - result1 []registry.CSVAndChannelInfo - result2 error - }{result1, result2} -} - -func (fake *FakeSource) ListLatestCSVsForCRDReturnsOnCall(i int, result1 []registry.CSVAndChannelInfo, result2 error) { - fake.ListLatestCSVsForCRDStub = nil - if fake.listLatestCSVsForCRDReturnsOnCall == nil { - fake.listLatestCSVsForCRDReturnsOnCall = make(map[int]struct { - result1 []registry.CSVAndChannelInfo - result2 error - }) - } - fake.listLatestCSVsForCRDReturnsOnCall[i] = struct { - result1 []registry.CSVAndChannelInfo - result2 error - }{result1, result2} -} - -func (fake *FakeSource) Invocations() map[string][][]interface{} { - fake.invocationsMutex.RLock() - defer fake.invocationsMutex.RUnlock() - fake.findCSVForPackageNameUnderChannelMutex.RLock() - defer fake.findCSVForPackageNameUnderChannelMutex.RUnlock() - fake.findReplacementCSVForPackageNameUnderChannelMutex.RLock() - defer fake.findReplacementCSVForPackageNameUnderChannelMutex.RUnlock() - fake.allPackagesMutex.RLock() - defer fake.allPackagesMutex.RUnlock() - fake.findReplacementCSVForNameMutex.RLock() - defer fake.findReplacementCSVForNameMutex.RUnlock() - fake.findCSVByNameMutex.RLock() - defer fake.findCSVByNameMutex.RUnlock() - fake.listServicesMutex.RLock() - defer fake.listServicesMutex.RUnlock() - fake.findCRDByKeyMutex.RLock() - defer fake.findCRDByKeyMutex.RUnlock() - fake.listLatestCSVsForCRDMutex.RLock() - defer fake.listLatestCSVsForCRDMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} - for key, value := range fake.invocations { - copiedInvocations[key] = value - } - return copiedInvocations -} - -func (fake *FakeSource) recordInvocation(key string, args []interface{}) { - fake.invocationsMutex.Lock() - defer fake.invocationsMutex.Unlock() - if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} - } - if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} - } - fake.invocations[key] = append(fake.invocations[key], args) -} - -var _ registry.Source = new(FakeSource) diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/fake_resolver.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/fake_resolver.go new file mode 100644 index 0000000000..52e00eca27 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/fake_resolver.go @@ -0,0 +1,123 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package fakes + +import ( + sync "sync" + + v1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + resolver "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver" +) + +type FakeResolver struct { + ResolveStepsStub func(string, resolver.SourceQuerier) ([]*v1alpha1.Step, []*v1alpha1.Subscription, error) + resolveStepsMutex sync.RWMutex + resolveStepsArgsForCall []struct { + arg1 string + arg2 resolver.SourceQuerier + } + resolveStepsReturns struct { + result1 []*v1alpha1.Step + result2 []*v1alpha1.Subscription + result3 error + } + resolveStepsReturnsOnCall map[int]struct { + result1 []*v1alpha1.Step + result2 []*v1alpha1.Subscription + result3 error + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *FakeResolver) ResolveSteps(arg1 string, arg2 resolver.SourceQuerier) ([]*v1alpha1.Step, []*v1alpha1.Subscription, error) { + fake.resolveStepsMutex.Lock() + ret, specificReturn := fake.resolveStepsReturnsOnCall[len(fake.resolveStepsArgsForCall)] + fake.resolveStepsArgsForCall = append(fake.resolveStepsArgsForCall, struct { + arg1 string + arg2 resolver.SourceQuerier + }{arg1, arg2}) + fake.recordInvocation("ResolveSteps", []interface{}{arg1, arg2}) + fake.resolveStepsMutex.Unlock() + if fake.ResolveStepsStub != nil { + return fake.ResolveStepsStub(arg1, arg2) + } + if specificReturn { + return ret.result1, ret.result2, ret.result3 + } + fakeReturns := fake.resolveStepsReturns + return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 +} + +func (fake *FakeResolver) ResolveStepsCallCount() int { + fake.resolveStepsMutex.RLock() + defer fake.resolveStepsMutex.RUnlock() + return len(fake.resolveStepsArgsForCall) +} + +func (fake *FakeResolver) ResolveStepsCalls(stub func(string, resolver.SourceQuerier) ([]*v1alpha1.Step, []*v1alpha1.Subscription, error)) { + fake.resolveStepsMutex.Lock() + defer fake.resolveStepsMutex.Unlock() + fake.ResolveStepsStub = stub +} + +func (fake *FakeResolver) ResolveStepsArgsForCall(i int) (string, resolver.SourceQuerier) { + fake.resolveStepsMutex.RLock() + defer fake.resolveStepsMutex.RUnlock() + argsForCall := fake.resolveStepsArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2 +} + +func (fake *FakeResolver) ResolveStepsReturns(result1 []*v1alpha1.Step, result2 []*v1alpha1.Subscription, result3 error) { + fake.resolveStepsMutex.Lock() + defer fake.resolveStepsMutex.Unlock() + fake.ResolveStepsStub = nil + fake.resolveStepsReturns = struct { + result1 []*v1alpha1.Step + result2 []*v1alpha1.Subscription + result3 error + }{result1, result2, result3} +} + +func (fake *FakeResolver) ResolveStepsReturnsOnCall(i int, result1 []*v1alpha1.Step, result2 []*v1alpha1.Subscription, result3 error) { + fake.resolveStepsMutex.Lock() + defer fake.resolveStepsMutex.Unlock() + fake.ResolveStepsStub = nil + if fake.resolveStepsReturnsOnCall == nil { + fake.resolveStepsReturnsOnCall = make(map[int]struct { + result1 []*v1alpha1.Step + result2 []*v1alpha1.Subscription + result3 error + }) + } + fake.resolveStepsReturnsOnCall[i] = struct { + result1 []*v1alpha1.Step + result2 []*v1alpha1.Subscription + result3 error + }{result1, result2, result3} +} + +func (fake *FakeResolver) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.resolveStepsMutex.RLock() + defer fake.resolveStepsMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *FakeResolver) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} + +var _ resolver.Resolver = new(FakeResolver) diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/fake_resources.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/fake_resources.go deleted file mode 100644 index 685b50a9a6..0000000000 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/fake_resources.go +++ /dev/null @@ -1,71 +0,0 @@ -package fakes - -import ( - yaml "gopkg.in/yaml.v2" - - "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" -) - -func FakeConfigMapData() map[string]string { - data := make(map[string]string) - yaml, err := yaml.Marshal([]v1beta1.CustomResourceDefinition{FakeCRD("fake-crd")}) - if err != nil { - return data - } - - data["customResourceDefinitions"] = string(yaml) - return data -} - -func FakeInstallPlan(names ...string) v1alpha1.InstallPlan { - return v1alpha1.InstallPlan{ - Spec: v1alpha1.InstallPlanSpec{ - ClusterServiceVersionNames: names, - }, - Status: v1alpha1.InstallPlanStatus{ - Plan: []v1alpha1.Step{}, - }, - } -} - -func FakeCSV(name string, owned, required []string) v1alpha1.ClusterServiceVersion { - requiredCRDDescs := make([]v1alpha1.CRDDescription, 0) - for _, name := range required { - requiredCRDDescs = append(requiredCRDDescs, v1alpha1.CRDDescription{Name: name, Version: "v1", Kind: name}) - } - - ownedCRDDescs := make([]v1alpha1.CRDDescription, 0) - for _, name := range owned { - ownedCRDDescs = append(ownedCRDDescs, v1alpha1.CRDDescription{Name: name, Version: "v1", Kind: name}) - } - - return v1alpha1.ClusterServiceVersion{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - }, - Spec: v1alpha1.ClusterServiceVersionSpec{ - CustomResourceDefinitions: v1alpha1.CustomResourceDefinitions{ - Owned: ownedCRDDescs, - Required: requiredCRDDescs, - }, - }, - } -} - -func FakeCRD(name string) v1beta1.CustomResourceDefinition { - return v1beta1.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - }, - Spec: v1beta1.CustomResourceDefinitionSpec{ - Group: name + "group", - Version: "v1", - Names: v1beta1.CustomResourceDefinitionNames{ - Kind: name, - }, - }, - } -} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/fake_strategy.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/fake_strategy.go index aad453f2a2..e0816cd254 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/fake_strategy.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/fake_strategy.go @@ -2,16 +2,17 @@ package fakes import ( - "sync" + sync "sync" - "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install" + install "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install" ) type FakeStrategy struct { GetStrategyNameStub func() string getStrategyNameMutex sync.RWMutex - getStrategyNameArgsForCall []struct{} - getStrategyNameReturns struct { + getStrategyNameArgsForCall []struct { + } + getStrategyNameReturns struct { result1 string } getStrategyNameReturnsOnCall map[int]struct { @@ -24,7 +25,8 @@ type FakeStrategy struct { func (fake *FakeStrategy) GetStrategyName() string { fake.getStrategyNameMutex.Lock() ret, specificReturn := fake.getStrategyNameReturnsOnCall[len(fake.getStrategyNameArgsForCall)] - fake.getStrategyNameArgsForCall = append(fake.getStrategyNameArgsForCall, struct{}{}) + fake.getStrategyNameArgsForCall = append(fake.getStrategyNameArgsForCall, struct { + }{}) fake.recordInvocation("GetStrategyName", []interface{}{}) fake.getStrategyNameMutex.Unlock() if fake.GetStrategyNameStub != nil { @@ -33,7 +35,8 @@ func (fake *FakeStrategy) GetStrategyName() string { if specificReturn { return ret.result1 } - return fake.getStrategyNameReturns.result1 + fakeReturns := fake.getStrategyNameReturns + return fakeReturns.result1 } func (fake *FakeStrategy) GetStrategyNameCallCount() int { @@ -42,7 +45,15 @@ func (fake *FakeStrategy) GetStrategyNameCallCount() int { return len(fake.getStrategyNameArgsForCall) } +func (fake *FakeStrategy) GetStrategyNameCalls(stub func() string) { + fake.getStrategyNameMutex.Lock() + defer fake.getStrategyNameMutex.Unlock() + fake.GetStrategyNameStub = stub +} + func (fake *FakeStrategy) GetStrategyNameReturns(result1 string) { + fake.getStrategyNameMutex.Lock() + defer fake.getStrategyNameMutex.Unlock() fake.GetStrategyNameStub = nil fake.getStrategyNameReturns = struct { result1 string @@ -50,6 +61,8 @@ func (fake *FakeStrategy) GetStrategyNameReturns(result1 string) { } func (fake *FakeStrategy) GetStrategyNameReturnsOnCall(i int, result1 string) { + fake.getStrategyNameMutex.Lock() + defer fake.getStrategyNameMutex.Unlock() fake.GetStrategyNameStub = nil if fake.getStrategyNameReturnsOnCall == nil { fake.getStrategyNameReturnsOnCall = make(map[int]struct { diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/fake_strategy_installer.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/fake_strategy_installer.go index 76bbd91c65..eacb2e27d3 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/fake_strategy_installer.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/fake_strategy_installer.go @@ -2,27 +2,16 @@ package fakes import ( - "sync" + sync "sync" - "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install" + install "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install" ) type FakeStrategyInstaller struct { - InstallStub func(strategy install.Strategy) error - installMutex sync.RWMutex - installArgsForCall []struct { - strategy install.Strategy - } - installReturns struct { - result1 error - } - installReturnsOnCall map[int]struct { - result1 error - } - CheckInstalledStub func(strategy install.Strategy) (bool, error) + CheckInstalledStub func(install.Strategy) (bool, error) checkInstalledMutex sync.RWMutex checkInstalledArgsForCall []struct { - strategy install.Strategy + arg1 install.Strategy } checkInstalledReturns struct { result1 bool @@ -32,73 +21,37 @@ type FakeStrategyInstaller struct { result1 bool result2 error } - invocations map[string][][]interface{} - invocationsMutex sync.RWMutex -} - -func (fake *FakeStrategyInstaller) Install(strategy install.Strategy) error { - fake.installMutex.Lock() - ret, specificReturn := fake.installReturnsOnCall[len(fake.installArgsForCall)] - fake.installArgsForCall = append(fake.installArgsForCall, struct { - strategy install.Strategy - }{strategy}) - fake.recordInvocation("Install", []interface{}{strategy}) - fake.installMutex.Unlock() - if fake.InstallStub != nil { - return fake.InstallStub(strategy) - } - if specificReturn { - return ret.result1 + InstallStub func(install.Strategy) error + installMutex sync.RWMutex + installArgsForCall []struct { + arg1 install.Strategy } - return fake.installReturns.result1 -} - -func (fake *FakeStrategyInstaller) InstallCallCount() int { - fake.installMutex.RLock() - defer fake.installMutex.RUnlock() - return len(fake.installArgsForCall) -} - -func (fake *FakeStrategyInstaller) InstallArgsForCall(i int) install.Strategy { - fake.installMutex.RLock() - defer fake.installMutex.RUnlock() - return fake.installArgsForCall[i].strategy -} - -func (fake *FakeStrategyInstaller) InstallReturns(result1 error) { - fake.InstallStub = nil - fake.installReturns = struct { + installReturns struct { result1 error - }{result1} -} - -func (fake *FakeStrategyInstaller) InstallReturnsOnCall(i int, result1 error) { - fake.InstallStub = nil - if fake.installReturnsOnCall == nil { - fake.installReturnsOnCall = make(map[int]struct { - result1 error - }) } - fake.installReturnsOnCall[i] = struct { + installReturnsOnCall map[int]struct { result1 error - }{result1} + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex } -func (fake *FakeStrategyInstaller) CheckInstalled(strategy install.Strategy) (bool, error) { +func (fake *FakeStrategyInstaller) CheckInstalled(arg1 install.Strategy) (bool, error) { fake.checkInstalledMutex.Lock() ret, specificReturn := fake.checkInstalledReturnsOnCall[len(fake.checkInstalledArgsForCall)] fake.checkInstalledArgsForCall = append(fake.checkInstalledArgsForCall, struct { - strategy install.Strategy - }{strategy}) - fake.recordInvocation("CheckInstalled", []interface{}{strategy}) + arg1 install.Strategy + }{arg1}) + fake.recordInvocation("CheckInstalled", []interface{}{arg1}) fake.checkInstalledMutex.Unlock() if fake.CheckInstalledStub != nil { - return fake.CheckInstalledStub(strategy) + return fake.CheckInstalledStub(arg1) } if specificReturn { return ret.result1, ret.result2 } - return fake.checkInstalledReturns.result1, fake.checkInstalledReturns.result2 + fakeReturns := fake.checkInstalledReturns + return fakeReturns.result1, fakeReturns.result2 } func (fake *FakeStrategyInstaller) CheckInstalledCallCount() int { @@ -107,13 +60,22 @@ func (fake *FakeStrategyInstaller) CheckInstalledCallCount() int { return len(fake.checkInstalledArgsForCall) } +func (fake *FakeStrategyInstaller) CheckInstalledCalls(stub func(install.Strategy) (bool, error)) { + fake.checkInstalledMutex.Lock() + defer fake.checkInstalledMutex.Unlock() + fake.CheckInstalledStub = stub +} + func (fake *FakeStrategyInstaller) CheckInstalledArgsForCall(i int) install.Strategy { fake.checkInstalledMutex.RLock() defer fake.checkInstalledMutex.RUnlock() - return fake.checkInstalledArgsForCall[i].strategy + argsForCall := fake.checkInstalledArgsForCall[i] + return argsForCall.arg1 } func (fake *FakeStrategyInstaller) CheckInstalledReturns(result1 bool, result2 error) { + fake.checkInstalledMutex.Lock() + defer fake.checkInstalledMutex.Unlock() fake.CheckInstalledStub = nil fake.checkInstalledReturns = struct { result1 bool @@ -122,6 +84,8 @@ func (fake *FakeStrategyInstaller) CheckInstalledReturns(result1 bool, result2 e } func (fake *FakeStrategyInstaller) CheckInstalledReturnsOnCall(i int, result1 bool, result2 error) { + fake.checkInstalledMutex.Lock() + defer fake.checkInstalledMutex.Unlock() fake.CheckInstalledStub = nil if fake.checkInstalledReturnsOnCall == nil { fake.checkInstalledReturnsOnCall = make(map[int]struct { @@ -135,13 +99,73 @@ func (fake *FakeStrategyInstaller) CheckInstalledReturnsOnCall(i int, result1 bo }{result1, result2} } +func (fake *FakeStrategyInstaller) Install(arg1 install.Strategy) error { + fake.installMutex.Lock() + ret, specificReturn := fake.installReturnsOnCall[len(fake.installArgsForCall)] + fake.installArgsForCall = append(fake.installArgsForCall, struct { + arg1 install.Strategy + }{arg1}) + fake.recordInvocation("Install", []interface{}{arg1}) + fake.installMutex.Unlock() + if fake.InstallStub != nil { + return fake.InstallStub(arg1) + } + if specificReturn { + return ret.result1 + } + fakeReturns := fake.installReturns + return fakeReturns.result1 +} + +func (fake *FakeStrategyInstaller) InstallCallCount() int { + fake.installMutex.RLock() + defer fake.installMutex.RUnlock() + return len(fake.installArgsForCall) +} + +func (fake *FakeStrategyInstaller) InstallCalls(stub func(install.Strategy) error) { + fake.installMutex.Lock() + defer fake.installMutex.Unlock() + fake.InstallStub = stub +} + +func (fake *FakeStrategyInstaller) InstallArgsForCall(i int) install.Strategy { + fake.installMutex.RLock() + defer fake.installMutex.RUnlock() + argsForCall := fake.installArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FakeStrategyInstaller) InstallReturns(result1 error) { + fake.installMutex.Lock() + defer fake.installMutex.Unlock() + fake.InstallStub = nil + fake.installReturns = struct { + result1 error + }{result1} +} + +func (fake *FakeStrategyInstaller) InstallReturnsOnCall(i int, result1 error) { + fake.installMutex.Lock() + defer fake.installMutex.Unlock() + fake.InstallStub = nil + if fake.installReturnsOnCall == nil { + fake.installReturnsOnCall = make(map[int]struct { + result1 error + }) + } + fake.installReturnsOnCall[i] = struct { + result1 error + }{result1} +} + func (fake *FakeStrategyInstaller) Invocations() map[string][][]interface{} { fake.invocationsMutex.RLock() defer fake.invocationsMutex.RUnlock() - fake.installMutex.RLock() - defer fake.installMutex.RUnlock() fake.checkInstalledMutex.RLock() defer fake.checkInstalledMutex.RUnlock() + fake.installMutex.RLock() + defer fake.installMutex.RUnlock() copiedInvocations := map[string][][]interface{}{} for key, value := range fake.invocations { copiedInvocations[key] = value diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/fake_strategy_resolver.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/fake_strategy_resolver.go index c40f559d5c..17f60a9a6a 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/fake_strategy_resolver.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/fake_strategy_resolver.go @@ -2,19 +2,36 @@ package fakes import ( - "sync" + sync "sync" - "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" - "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install" - "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient" - "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil" + v1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + install "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install" + operatorclient "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient" + operatorlister "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister" + ownerutil "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil" ) type FakeStrategyResolverInterface struct { - UnmarshalStrategyStub func(s v1alpha1.NamedInstallStrategy) (strategy install.Strategy, err error) + InstallerForStrategyStub func(string, operatorclient.ClientInterface, operatorlister.OperatorLister, ownerutil.Owner, map[string]string, install.Strategy) install.StrategyInstaller + installerForStrategyMutex sync.RWMutex + installerForStrategyArgsForCall []struct { + arg1 string + arg2 operatorclient.ClientInterface + arg3 operatorlister.OperatorLister + arg4 ownerutil.Owner + arg5 map[string]string + arg6 install.Strategy + } + installerForStrategyReturns struct { + result1 install.StrategyInstaller + } + installerForStrategyReturnsOnCall map[int]struct { + result1 install.StrategyInstaller + } + UnmarshalStrategyStub func(v1alpha1.NamedInstallStrategy) (install.Strategy, error) unmarshalStrategyMutex sync.RWMutex unmarshalStrategyArgsForCall []struct { - s v1alpha1.NamedInstallStrategy + arg1 v1alpha1.NamedInstallStrategy } unmarshalStrategyReturns struct { result1 install.Strategy @@ -24,39 +41,91 @@ type FakeStrategyResolverInterface struct { result1 install.Strategy result2 error } - InstallerForStrategyStub func(strategyName string, opClient operatorclient.ClientInterface, owner ownerutil.Owner, previousStrategy install.Strategy) install.StrategyInstaller - installerForStrategyMutex sync.RWMutex - installerForStrategyArgsForCall []struct { - strategyName string - opClient operatorclient.ClientInterface - owner ownerutil.Owner - previousStrategy install.Strategy + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *FakeStrategyResolverInterface) InstallerForStrategy(arg1 string, arg2 operatorclient.ClientInterface, arg3 operatorlister.OperatorLister, arg4 ownerutil.Owner, arg5 map[string]string, arg6 install.Strategy) install.StrategyInstaller { + fake.installerForStrategyMutex.Lock() + ret, specificReturn := fake.installerForStrategyReturnsOnCall[len(fake.installerForStrategyArgsForCall)] + fake.installerForStrategyArgsForCall = append(fake.installerForStrategyArgsForCall, struct { + arg1 string + arg2 operatorclient.ClientInterface + arg3 operatorlister.OperatorLister + arg4 ownerutil.Owner + arg5 map[string]string + arg6 install.Strategy + }{arg1, arg2, arg3, arg4, arg5, arg6}) + fake.recordInvocation("InstallerForStrategy", []interface{}{arg1, arg2, arg3, arg4, arg5, arg6}) + fake.installerForStrategyMutex.Unlock() + if fake.InstallerForStrategyStub != nil { + return fake.InstallerForStrategyStub(arg1, arg2, arg3, arg4, arg5, arg6) } - installerForStrategyReturns struct { - result1 install.StrategyInstaller + if specificReturn { + return ret.result1 } - installerForStrategyReturnsOnCall map[int]struct { + fakeReturns := fake.installerForStrategyReturns + return fakeReturns.result1 +} + +func (fake *FakeStrategyResolverInterface) InstallerForStrategyCallCount() int { + fake.installerForStrategyMutex.RLock() + defer fake.installerForStrategyMutex.RUnlock() + return len(fake.installerForStrategyArgsForCall) +} + +func (fake *FakeStrategyResolverInterface) InstallerForStrategyCalls(stub func(string, operatorclient.ClientInterface, operatorlister.OperatorLister, ownerutil.Owner, map[string]string, install.Strategy) install.StrategyInstaller) { + fake.installerForStrategyMutex.Lock() + defer fake.installerForStrategyMutex.Unlock() + fake.InstallerForStrategyStub = stub +} + +func (fake *FakeStrategyResolverInterface) InstallerForStrategyArgsForCall(i int) (string, operatorclient.ClientInterface, operatorlister.OperatorLister, ownerutil.Owner, map[string]string, install.Strategy) { + fake.installerForStrategyMutex.RLock() + defer fake.installerForStrategyMutex.RUnlock() + argsForCall := fake.installerForStrategyArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4, argsForCall.arg5, argsForCall.arg6 +} + +func (fake *FakeStrategyResolverInterface) InstallerForStrategyReturns(result1 install.StrategyInstaller) { + fake.installerForStrategyMutex.Lock() + defer fake.installerForStrategyMutex.Unlock() + fake.InstallerForStrategyStub = nil + fake.installerForStrategyReturns = struct { result1 install.StrategyInstaller + }{result1} +} + +func (fake *FakeStrategyResolverInterface) InstallerForStrategyReturnsOnCall(i int, result1 install.StrategyInstaller) { + fake.installerForStrategyMutex.Lock() + defer fake.installerForStrategyMutex.Unlock() + fake.InstallerForStrategyStub = nil + if fake.installerForStrategyReturnsOnCall == nil { + fake.installerForStrategyReturnsOnCall = make(map[int]struct { + result1 install.StrategyInstaller + }) } - invocations map[string][][]interface{} - invocationsMutex sync.RWMutex + fake.installerForStrategyReturnsOnCall[i] = struct { + result1 install.StrategyInstaller + }{result1} } -func (fake *FakeStrategyResolverInterface) UnmarshalStrategy(s v1alpha1.NamedInstallStrategy) (strategy install.Strategy, err error) { +func (fake *FakeStrategyResolverInterface) UnmarshalStrategy(arg1 v1alpha1.NamedInstallStrategy) (install.Strategy, error) { fake.unmarshalStrategyMutex.Lock() ret, specificReturn := fake.unmarshalStrategyReturnsOnCall[len(fake.unmarshalStrategyArgsForCall)] fake.unmarshalStrategyArgsForCall = append(fake.unmarshalStrategyArgsForCall, struct { - s v1alpha1.NamedInstallStrategy - }{s}) - fake.recordInvocation("UnmarshalStrategy", []interface{}{s}) + arg1 v1alpha1.NamedInstallStrategy + }{arg1}) + fake.recordInvocation("UnmarshalStrategy", []interface{}{arg1}) fake.unmarshalStrategyMutex.Unlock() if fake.UnmarshalStrategyStub != nil { - return fake.UnmarshalStrategyStub(s) + return fake.UnmarshalStrategyStub(arg1) } if specificReturn { return ret.result1, ret.result2 } - return fake.unmarshalStrategyReturns.result1, fake.unmarshalStrategyReturns.result2 + fakeReturns := fake.unmarshalStrategyReturns + return fakeReturns.result1, fakeReturns.result2 } func (fake *FakeStrategyResolverInterface) UnmarshalStrategyCallCount() int { @@ -65,13 +134,22 @@ func (fake *FakeStrategyResolverInterface) UnmarshalStrategyCallCount() int { return len(fake.unmarshalStrategyArgsForCall) } +func (fake *FakeStrategyResolverInterface) UnmarshalStrategyCalls(stub func(v1alpha1.NamedInstallStrategy) (install.Strategy, error)) { + fake.unmarshalStrategyMutex.Lock() + defer fake.unmarshalStrategyMutex.Unlock() + fake.UnmarshalStrategyStub = stub +} + func (fake *FakeStrategyResolverInterface) UnmarshalStrategyArgsForCall(i int) v1alpha1.NamedInstallStrategy { fake.unmarshalStrategyMutex.RLock() defer fake.unmarshalStrategyMutex.RUnlock() - return fake.unmarshalStrategyArgsForCall[i].s + argsForCall := fake.unmarshalStrategyArgsForCall[i] + return argsForCall.arg1 } func (fake *FakeStrategyResolverInterface) UnmarshalStrategyReturns(result1 install.Strategy, result2 error) { + fake.unmarshalStrategyMutex.Lock() + defer fake.unmarshalStrategyMutex.Unlock() fake.UnmarshalStrategyStub = nil fake.unmarshalStrategyReturns = struct { result1 install.Strategy @@ -80,6 +158,8 @@ func (fake *FakeStrategyResolverInterface) UnmarshalStrategyReturns(result1 inst } func (fake *FakeStrategyResolverInterface) UnmarshalStrategyReturnsOnCall(i int, result1 install.Strategy, result2 error) { + fake.unmarshalStrategyMutex.Lock() + defer fake.unmarshalStrategyMutex.Unlock() fake.UnmarshalStrategyStub = nil if fake.unmarshalStrategyReturnsOnCall == nil { fake.unmarshalStrategyReturnsOnCall = make(map[int]struct { @@ -93,64 +173,13 @@ func (fake *FakeStrategyResolverInterface) UnmarshalStrategyReturnsOnCall(i int, }{result1, result2} } -func (fake *FakeStrategyResolverInterface) InstallerForStrategy(strategyName string, opClient operatorclient.ClientInterface, owner ownerutil.Owner, previousStrategy install.Strategy) install.StrategyInstaller { - fake.installerForStrategyMutex.Lock() - ret, specificReturn := fake.installerForStrategyReturnsOnCall[len(fake.installerForStrategyArgsForCall)] - fake.installerForStrategyArgsForCall = append(fake.installerForStrategyArgsForCall, struct { - strategyName string - opClient operatorclient.ClientInterface - owner ownerutil.Owner - previousStrategy install.Strategy - }{strategyName, opClient, owner, previousStrategy}) - fake.recordInvocation("InstallerForStrategy", []interface{}{strategyName, opClient, owner, previousStrategy}) - fake.installerForStrategyMutex.Unlock() - if fake.InstallerForStrategyStub != nil { - return fake.InstallerForStrategyStub(strategyName, opClient, owner, previousStrategy) - } - if specificReturn { - return ret.result1 - } - return fake.installerForStrategyReturns.result1 -} - -func (fake *FakeStrategyResolverInterface) InstallerForStrategyCallCount() int { - fake.installerForStrategyMutex.RLock() - defer fake.installerForStrategyMutex.RUnlock() - return len(fake.installerForStrategyArgsForCall) -} - -func (fake *FakeStrategyResolverInterface) InstallerForStrategyArgsForCall(i int) (string, operatorclient.ClientInterface, ownerutil.Owner, install.Strategy) { - fake.installerForStrategyMutex.RLock() - defer fake.installerForStrategyMutex.RUnlock() - return fake.installerForStrategyArgsForCall[i].strategyName, fake.installerForStrategyArgsForCall[i].opClient, fake.installerForStrategyArgsForCall[i].owner, fake.installerForStrategyArgsForCall[i].previousStrategy -} - -func (fake *FakeStrategyResolverInterface) InstallerForStrategyReturns(result1 install.StrategyInstaller) { - fake.InstallerForStrategyStub = nil - fake.installerForStrategyReturns = struct { - result1 install.StrategyInstaller - }{result1} -} - -func (fake *FakeStrategyResolverInterface) InstallerForStrategyReturnsOnCall(i int, result1 install.StrategyInstaller) { - fake.InstallerForStrategyStub = nil - if fake.installerForStrategyReturnsOnCall == nil { - fake.installerForStrategyReturnsOnCall = make(map[int]struct { - result1 install.StrategyInstaller - }) - } - fake.installerForStrategyReturnsOnCall[i] = struct { - result1 install.StrategyInstaller - }{result1} -} - func (fake *FakeStrategyResolverInterface) Invocations() map[string][][]interface{} { fake.invocationsMutex.RLock() defer fake.invocationsMutex.RUnlock() - fake.unmarshalStrategyMutex.RLock() - defer fake.unmarshalStrategyMutex.RUnlock() fake.installerForStrategyMutex.RLock() defer fake.installerForStrategyMutex.RUnlock() + fake.unmarshalStrategyMutex.RLock() + defer fake.unmarshalStrategyMutex.RUnlock() copiedInvocations := map[string][][]interface{}{} for key, value := range fake.invocations { copiedInvocations[key] = value diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/event/event.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/event/event.go new file mode 100644 index 0000000000..79f73a0d9f --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/event/event.go @@ -0,0 +1,23 @@ +package event + +import ( + "github.com/golang/glog" + v1 "k8s.io/api/core/v1" + typedcorev1 "k8s.io/client-go/kubernetes/typed/core/v1" + "k8s.io/client-go/tools/record" + + "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/scheme" +) + +const component string = "operator-lifecycle-manager" + +// NewRecorder returns an EventRecorder type that can be +// used to post Events to different object's lifecycles. +func NewRecorder(event typedcorev1.EventInterface) (record.EventRecorder, error) { + eventBroadcaster := record.NewBroadcaster() + eventBroadcaster.StartLogging(glog.Infof) + eventBroadcaster.StartRecordingToSink(&typedcorev1.EventSinkImpl{Interface: event}) + recorder := eventBroadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: component}) + + return recorder, nil +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/index/label.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/index/label.go new file mode 100644 index 0000000000..52ccd29bea --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/index/label.go @@ -0,0 +1,60 @@ +package indexer + +import ( + "fmt" + + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +const ( + // MetaLabelIndexFuncKey is the recommended key to use for registering the index func with an indexer. + MetaLabelIndexFuncKey string = "metalabelindexfunc" +) + +// MetaLabelIndexFunc returns indicies from the labels of the given object. +func MetaLabelIndexFunc(obj interface{}) ([]string, error) { + indicies := []string{} + m, err := meta.Accessor(obj) + if err != nil { + return indicies, fmt.Errorf("object has no meta: %v", err) + } + + for k, v := range m.GetLabels() { + indicies = append(indicies, fmt.Sprintf("%s=%s", k, v)) + } + + return indicies, nil +} + +// LabelIndexKeys returns the union of indexed cache keys in the given indexers matching the same labels as the given selector +func LabelIndexKeys(indexers map[string]cache.Indexer, labelSets ...labels.Set) ([]string, error) { + keySet := map[string]struct{}{} + keys := []string{} + for _, indexer := range indexers { + for _, labelSet := range labelSets { + for key, value := range labelSet { + apiLabelKey := fmt.Sprintf("%s=%s", key, value) + cacheKeys, err := indexer.IndexKeys(MetaLabelIndexFuncKey, apiLabelKey) + if err != nil { + return nil, err + } + + for _, cacheKey := range cacheKeys { + // Detect duplication + if _, ok := keySet[cacheKey]; ok { + continue + } + + // Add to set + keySet[cacheKey] = struct{}{} + keys = append(keys, cacheKey) + } + + } + } + } + + return keys, nil +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/labeler/labeler.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/labeler/labeler.go new file mode 100644 index 0000000000..22a8e73207 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/labeler/labeler.go @@ -0,0 +1,19 @@ +package labeler + +import ( + "k8s.io/apimachinery/pkg/labels" +) + +// Labeler can provide label sets that describe an object +type Labeler interface { + // LabelSetsFor returns label sets that describe the given object + LabelSetsFor(obj interface{}) ([]labels.Set, error) +} + +// Func is a function type that implements the Labeler interface +type Func func(obj interface{}) ([]labels.Set, error) + +// LabelSetsFor calls LabelSetsFor on itself to satisfy the Labeler interface +func (l Func) LabelSetsFor(obj interface{}) ([]labels.Set, error) { + return l(obj) +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient/apiservice.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient/apiservice.go new file mode 100644 index 0000000000..76b4792dd8 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient/apiservice.go @@ -0,0 +1,39 @@ +package operatorclient + +import ( + "fmt" + + "github.com/golang/glog" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" +) + +// CreateAPIService creates the APIService. +func (c *Client) CreateAPIService(ig *apiregistrationv1.APIService) (*apiregistrationv1.APIService, error) { + return c.ApiregistrationV1Interface().ApiregistrationV1().APIServices().Create(ig) +} + +// GetAPIService returns the existing APIService. +func (c *Client) GetAPIService(name string) (*apiregistrationv1.APIService, error) { + return c.ApiregistrationV1Interface().ApiregistrationV1().APIServices().Get(name, metav1.GetOptions{}) +} + +// DeleteAPIService deletes the APIService. +func (c *Client) DeleteAPIService(name string, options *metav1.DeleteOptions) error { + return c.ApiregistrationV1Interface().ApiregistrationV1().APIServices().Delete(name, options) +} + +// UpdateAPIService will update the given APIService resource. +func (c *Client) UpdateAPIService(apiService *apiregistrationv1.APIService) (*apiregistrationv1.APIService, error) { + glog.V(4).Infof("[UPDATE APIService]: %s", apiService.GetName()) + oldAPIService, err := c.GetAPIService(apiService.GetName()) + if err != nil { + return nil, err + } + patchBytes, err := createPatch(oldAPIService, apiService) + if err != nil { + return nil, fmt.Errorf("error creating patch for APIService: %v", err) + } + return c.ApiregistrationV1Interface().ApiregistrationV1().APIServices().Patch(apiService.GetName(), types.StrategicMergePatchType, patchBytes) +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient/client.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient/client.go index 6897d5421a..8a6ae14356 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient/client.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient/client.go @@ -1,9 +1,10 @@ package operatorclient import ( - log "github.com/sirupsen/logrus" + "github.com/sirupsen/logrus" appsv1 "k8s.io/api/apps/v1" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" apiextensions "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -11,13 +12,23 @@ import ( "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" + apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" + apiregistration "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset" ) type ClientInterface interface { KubernetesInterface() kubernetes.Interface ApiextensionsV1beta1Interface() apiextensions.Interface + ApiregistrationV1Interface() apiregistration.Interface + APIServiceClient CustomResourceClient + SecretClient + ServiceClient ServiceAccountClient + RoleClient + RoleBindingClient + ClusterRoleBindingClient + ClusterRoleClient DeploymentClient } @@ -36,7 +47,31 @@ type CustomResourceClient interface { ListCustomResource(apiGroup, version, namespace, resourceKind string) (*CustomResourceList, error) } -// ServiceAccountClient contains methods for manipulating ServiceAccount. +// APIServiceClient contains methods for manipulating APIServiceBindings. +type APIServiceClient interface { + CreateAPIService(*apiregistrationv1.APIService) (*apiregistrationv1.APIService, error) + GetAPIService(name string) (*apiregistrationv1.APIService, error) + UpdateAPIService(modified *apiregistrationv1.APIService) (*apiregistrationv1.APIService, error) + DeleteAPIService(name string, options *metav1.DeleteOptions) error +} + +// SecretClient contains methods for manipulating Secrets +type SecretClient interface { + CreateSecret(*v1.Secret) (*v1.Secret, error) + GetSecret(namespace, name string) (*v1.Secret, error) + UpdateSecret(modified *v1.Secret) (*v1.Secret, error) + DeleteSecret(namespace, name string, options *metav1.DeleteOptions) error +} + +// ServiceClient contains methods for manipulating Services +type ServiceClient interface { + CreateService(*v1.Service) (*v1.Service, error) + GetService(namespace, name string) (*v1.Service, error) + UpdateService(modified *v1.Service) (*v1.Service, error) + DeleteService(namespace, name string, options *metav1.DeleteOptions) error +} + +// ServiceAccountClient contains methods for manipulating ServiceAccounts. type ServiceAccountClient interface { CreateServiceAccount(*v1.ServiceAccount) (*v1.ServiceAccount, error) GetServiceAccount(namespace, name string) (*v1.ServiceAccount, error) @@ -44,6 +79,38 @@ type ServiceAccountClient interface { DeleteServiceAccount(namespace, name string, options *metav1.DeleteOptions) error } +// RoleClient contains methods for manipulating Roles. +type RoleClient interface { + CreateRole(*rbacv1.Role) (*rbacv1.Role, error) + GetRole(namespace, name string) (*rbacv1.Role, error) + UpdateRole(modified *rbacv1.Role) (*rbacv1.Role, error) + DeleteRole(namespace, name string, options *metav1.DeleteOptions) error +} + +// RoleBindingClient contains methods for manipulating RoleBindings. +type RoleBindingClient interface { + CreateRoleBinding(*rbacv1.RoleBinding) (*rbacv1.RoleBinding, error) + GetRoleBinding(namespace, name string) (*rbacv1.RoleBinding, error) + UpdateRoleBinding(modified *rbacv1.RoleBinding) (*rbacv1.RoleBinding, error) + DeleteRoleBinding(namespace, name string, options *metav1.DeleteOptions) error +} + +// ClusterRoleClient contains methods for manipulating ClusterRoleBindings. +type ClusterRoleClient interface { + CreateClusterRole(*rbacv1.ClusterRole) (*rbacv1.ClusterRole, error) + GetClusterRole(name string) (*rbacv1.ClusterRole, error) + UpdateClusterRole(modified *rbacv1.ClusterRole) (*rbacv1.ClusterRole, error) + DeleteClusterRole(name string, options *metav1.DeleteOptions) error +} + +// ClusterRoleBindingClient contains methods for manipulating ClusterRoleBindings. +type ClusterRoleBindingClient interface { + CreateClusterRoleBinding(*rbacv1.ClusterRoleBinding) (*rbacv1.ClusterRoleBinding, error) + GetClusterRoleBinding(name string) (*rbacv1.ClusterRoleBinding, error) + UpdateClusterRoleBinding(modified *rbacv1.ClusterRoleBinding) (*rbacv1.ClusterRoleBinding, error) + DeleteClusterRoleBinding(name string, options *metav1.DeleteOptions) error +} + // DeploymentClient contains methods for the Deployment resource. type DeploymentClient interface { GetDeployment(namespace, name string) (*appsv1.Deployment, error) @@ -66,31 +133,32 @@ var _ ClientInterface = &Client{} type Client struct { kubernetes.Interface extInterface apiextensions.Interface + regInterface apiregistration.Interface } // NewClient creates a kubernetes client or bails out on on failures. -func NewClientFromConfig(kubeconfig string) ClientInterface { +func NewClientFromConfig(kubeconfig string, logger *logrus.Logger) ClientInterface { var config *rest.Config var err error if kubeconfig != "" { - log.Infof("Loading kube client config from path %q", kubeconfig) + logger.Infof("Loading kube client config from path %q", kubeconfig) config, err = clientcmd.BuildConfigFromFlags("", kubeconfig) } else { - log.Infof("Using in-cluster kube client config") + logger.Infof("Using in-cluster kube client config") config, err = rest.InClusterConfig() } if err != nil { - log.Fatalf("Cannot load config for REST client: %v", err) + logger.Fatalf("Cannot load config for REST client: %v", err) } - return &Client{kubernetes.NewForConfigOrDie(config), apiextensions.NewForConfigOrDie(config)} + return &Client{kubernetes.NewForConfigOrDie(config), apiextensions.NewForConfigOrDie(config), apiregistration.NewForConfigOrDie(config)} } // NewClient creates a kubernetes client -func NewClient(k8sClient kubernetes.Interface, extclient apiextensions.Interface) ClientInterface { - return &Client{k8sClient, extclient} +func NewClient(k8sClient kubernetes.Interface, extclient apiextensions.Interface, regclient apiregistration.Interface) ClientInterface { + return &Client{k8sClient, extclient, regclient} } // KubernetesInterface returns the Kubernetes interface. @@ -98,7 +166,12 @@ func (c *Client) KubernetesInterface() kubernetes.Interface { return c.Interface } -// ApiextensionsV1beta1Interface returns the API extention interface. +// ApiextensionsV1beta1Interface returns the API extension interface. func (c *Client) ApiextensionsV1beta1Interface() apiextensions.Interface { return c.extInterface } + +// ApiregistrationV1Interface returns the API registration (aggregated apiserver) interface +func (c *Client) ApiregistrationV1Interface() apiregistration.Interface { + return c.regInterface +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient/clusterrole.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient/clusterrole.go new file mode 100644 index 0000000000..ee736fd2fd --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient/clusterrole.go @@ -0,0 +1,39 @@ +package operatorclient + +import ( + "fmt" + + "github.com/golang/glog" + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" +) + +// CreateClusterRole creates the ClusterRole. +func (c *Client) CreateClusterRole(r *rbacv1.ClusterRole) (*rbacv1.ClusterRole, error) { + return c.RbacV1().ClusterRoles().Create(r) +} + +// GetClusterRole returns the existing ClusterRole. +func (c *Client) GetClusterRole(name string) (*rbacv1.ClusterRole, error) { + return c.RbacV1().ClusterRoles().Get(name, metav1.GetOptions{}) +} + +// DeleteClusterRole deletes the ClusterRole +func (c *Client) DeleteClusterRole(name string, options *metav1.DeleteOptions) error { + return c.RbacV1().ClusterRoles().Delete(name, options) +} + +// UpdateClusterRole will update the given ClusterRole. +func (c *Client) UpdateClusterRole(crb *rbacv1.ClusterRole) (*rbacv1.ClusterRole, error) { + glog.V(4).Infof("[UPDATE Role]: %s", crb.GetName()) + oldCrb, err := c.GetClusterRole(crb.GetName()) + if err != nil { + return nil, err + } + patchBytes, err := createPatch(oldCrb, crb) + if err != nil { + return nil, fmt.Errorf("error creating patch for Role: %v", err) + } + return c.RbacV1().ClusterRoles().Patch(crb.GetName(), types.StrategicMergePatchType, patchBytes) +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient/clusterrolebinding.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient/clusterrolebinding.go new file mode 100755 index 0000000000..30e6826768 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient/clusterrolebinding.go @@ -0,0 +1,39 @@ +package operatorclient + +import ( + "fmt" + + "github.com/golang/glog" + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" +) + +// CreateRoleBinding creates the roleBinding. +func (c *Client) CreateClusterRoleBinding(ig *rbacv1.ClusterRoleBinding) (*rbacv1.ClusterRoleBinding, error) { + return c.RbacV1().ClusterRoleBindings().Create(ig) +} + +// GetRoleBinding returns the existing roleBinding. +func (c *Client) GetClusterRoleBinding(name string) (*rbacv1.ClusterRoleBinding, error) { + return c.RbacV1().ClusterRoleBindings().Get(name, metav1.GetOptions{}) +} + +// DeleteRoleBinding deletes the roleBinding. +func (c *Client) DeleteClusterRoleBinding(name string, options *metav1.DeleteOptions) error { + return c.RbacV1().ClusterRoleBindings().Delete(name, options) +} + +// UpdateRoleBinding will update the given RoleBinding resource. +func (c *Client) UpdateClusterRoleBinding(crb *rbacv1.ClusterRoleBinding) (*rbacv1.ClusterRoleBinding, error) { + glog.V(4).Infof("[UPDATE RoleBinding]: %s", crb.GetName()) + oldCrb, err := c.GetClusterRoleBinding(crb.GetName()) + if err != nil { + return nil, err + } + patchBytes, err := createPatch(oldCrb, crb) + if err != nil { + return nil, fmt.Errorf("error creating patch for RoleBinding: %v", err) + } + return c.RbacV1().ClusterRoleBindings().Patch(crb.GetName(), types.StrategicMergePatchType, patchBytes) +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient/mock_client.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient/mock_client.go index 2eabf328ca..418fc781c8 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient/mock_client.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient/mock_client.go @@ -8,11 +8,14 @@ import ( gomock "github.com/golang/mock/gomock" v1 "k8s.io/api/apps/v1" v10 "k8s.io/api/core/v1" + v11 "k8s.io/api/rbac/v1" clientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" - v11 "k8s.io/apimachinery/pkg/apis/meta/v1" + v12 "k8s.io/apimachinery/pkg/apis/meta/v1" unstructured "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" labels "k8s.io/apimachinery/pkg/labels" kubernetes "k8s.io/client-go/kubernetes" + v13 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" + clientset0 "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset" reflect "reflect" ) @@ -63,6 +66,69 @@ func (mr *MockClientInterfaceMockRecorder) ApiextensionsV1beta1Interface() *gomo return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ApiextensionsV1beta1Interface", reflect.TypeOf((*MockClientInterface)(nil).ApiextensionsV1beta1Interface)) } +// ApiregistrationV1Interface mocks base method +func (m *MockClientInterface) ApiregistrationV1Interface() clientset0.Interface { + ret := m.ctrl.Call(m, "ApiregistrationV1Interface") + ret0, _ := ret[0].(clientset0.Interface) + return ret0 +} + +// ApiregistrationV1Interface indicates an expected call of ApiregistrationV1Interface +func (mr *MockClientInterfaceMockRecorder) ApiregistrationV1Interface() *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ApiregistrationV1Interface", reflect.TypeOf((*MockClientInterface)(nil).ApiregistrationV1Interface)) +} + +// CreateAPIService mocks base method +func (m *MockClientInterface) CreateAPIService(arg0 *v13.APIService) (*v13.APIService, error) { + ret := m.ctrl.Call(m, "CreateAPIService", arg0) + ret0, _ := ret[0].(*v13.APIService) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateAPIService indicates an expected call of CreateAPIService +func (mr *MockClientInterfaceMockRecorder) CreateAPIService(arg0 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateAPIService", reflect.TypeOf((*MockClientInterface)(nil).CreateAPIService), arg0) +} + +// GetAPIService mocks base method +func (m *MockClientInterface) GetAPIService(name string) (*v13.APIService, error) { + ret := m.ctrl.Call(m, "GetAPIService", name) + ret0, _ := ret[0].(*v13.APIService) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetAPIService indicates an expected call of GetAPIService +func (mr *MockClientInterfaceMockRecorder) GetAPIService(name interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAPIService", reflect.TypeOf((*MockClientInterface)(nil).GetAPIService), name) +} + +// UpdateAPIService mocks base method +func (m *MockClientInterface) UpdateAPIService(modified *v13.APIService) (*v13.APIService, error) { + ret := m.ctrl.Call(m, "UpdateAPIService", modified) + ret0, _ := ret[0].(*v13.APIService) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateAPIService indicates an expected call of UpdateAPIService +func (mr *MockClientInterfaceMockRecorder) UpdateAPIService(modified interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateAPIService", reflect.TypeOf((*MockClientInterface)(nil).UpdateAPIService), modified) +} + +// DeleteAPIService mocks base method +func (m *MockClientInterface) DeleteAPIService(name string, options *v12.DeleteOptions) error { + ret := m.ctrl.Call(m, "DeleteAPIService", name, options) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteAPIService indicates an expected call of DeleteAPIService +func (mr *MockClientInterfaceMockRecorder) DeleteAPIService(name, options interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteAPIService", reflect.TypeOf((*MockClientInterface)(nil).DeleteAPIService), name, options) +} + // GetCustomResource mocks base method func (m *MockClientInterface) GetCustomResource(apiGroup, version, namespace, resourceKind, resourceName string) (*unstructured.Unstructured, error) { ret := m.ctrl.Call(m, "GetCustomResource", apiGroup, version, namespace, resourceKind, resourceName) @@ -199,6 +265,108 @@ func (mr *MockClientInterfaceMockRecorder) ListCustomResource(apiGroup, version, return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListCustomResource", reflect.TypeOf((*MockClientInterface)(nil).ListCustomResource), apiGroup, version, namespace, resourceKind) } +// CreateSecret mocks base method +func (m *MockClientInterface) CreateSecret(arg0 *v10.Secret) (*v10.Secret, error) { + ret := m.ctrl.Call(m, "CreateSecret", arg0) + ret0, _ := ret[0].(*v10.Secret) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateSecret indicates an expected call of CreateSecret +func (mr *MockClientInterfaceMockRecorder) CreateSecret(arg0 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateSecret", reflect.TypeOf((*MockClientInterface)(nil).CreateSecret), arg0) +} + +// GetSecret mocks base method +func (m *MockClientInterface) GetSecret(namespace, name string) (*v10.Secret, error) { + ret := m.ctrl.Call(m, "GetSecret", namespace, name) + ret0, _ := ret[0].(*v10.Secret) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSecret indicates an expected call of GetSecret +func (mr *MockClientInterfaceMockRecorder) GetSecret(namespace, name interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSecret", reflect.TypeOf((*MockClientInterface)(nil).GetSecret), namespace, name) +} + +// UpdateSecret mocks base method +func (m *MockClientInterface) UpdateSecret(modified *v10.Secret) (*v10.Secret, error) { + ret := m.ctrl.Call(m, "UpdateSecret", modified) + ret0, _ := ret[0].(*v10.Secret) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateSecret indicates an expected call of UpdateSecret +func (mr *MockClientInterfaceMockRecorder) UpdateSecret(modified interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateSecret", reflect.TypeOf((*MockClientInterface)(nil).UpdateSecret), modified) +} + +// DeleteSecret mocks base method +func (m *MockClientInterface) DeleteSecret(namespace, name string, options *v12.DeleteOptions) error { + ret := m.ctrl.Call(m, "DeleteSecret", namespace, name, options) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteSecret indicates an expected call of DeleteSecret +func (mr *MockClientInterfaceMockRecorder) DeleteSecret(namespace, name, options interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteSecret", reflect.TypeOf((*MockClientInterface)(nil).DeleteSecret), namespace, name, options) +} + +// CreateService mocks base method +func (m *MockClientInterface) CreateService(arg0 *v10.Service) (*v10.Service, error) { + ret := m.ctrl.Call(m, "CreateService", arg0) + ret0, _ := ret[0].(*v10.Service) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateService indicates an expected call of CreateService +func (mr *MockClientInterfaceMockRecorder) CreateService(arg0 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateService", reflect.TypeOf((*MockClientInterface)(nil).CreateService), arg0) +} + +// GetService mocks base method +func (m *MockClientInterface) GetService(namespace, name string) (*v10.Service, error) { + ret := m.ctrl.Call(m, "GetService", namespace, name) + ret0, _ := ret[0].(*v10.Service) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetService indicates an expected call of GetService +func (mr *MockClientInterfaceMockRecorder) GetService(namespace, name interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetService", reflect.TypeOf((*MockClientInterface)(nil).GetService), namespace, name) +} + +// UpdateService mocks base method +func (m *MockClientInterface) UpdateService(modified *v10.Service) (*v10.Service, error) { + ret := m.ctrl.Call(m, "UpdateService", modified) + ret0, _ := ret[0].(*v10.Service) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateService indicates an expected call of UpdateService +func (mr *MockClientInterfaceMockRecorder) UpdateService(modified interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateService", reflect.TypeOf((*MockClientInterface)(nil).UpdateService), modified) +} + +// DeleteService mocks base method +func (m *MockClientInterface) DeleteService(namespace, name string, options *v12.DeleteOptions) error { + ret := m.ctrl.Call(m, "DeleteService", namespace, name, options) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteService indicates an expected call of DeleteService +func (mr *MockClientInterfaceMockRecorder) DeleteService(namespace, name, options interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteService", reflect.TypeOf((*MockClientInterface)(nil).DeleteService), namespace, name, options) +} + // CreateServiceAccount mocks base method func (m *MockClientInterface) CreateServiceAccount(arg0 *v10.ServiceAccount) (*v10.ServiceAccount, error) { ret := m.ctrl.Call(m, "CreateServiceAccount", arg0) @@ -239,7 +407,7 @@ func (mr *MockClientInterfaceMockRecorder) UpdateServiceAccount(modified interfa } // DeleteServiceAccount mocks base method -func (m *MockClientInterface) DeleteServiceAccount(namespace, name string, options *v11.DeleteOptions) error { +func (m *MockClientInterface) DeleteServiceAccount(namespace, name string, options *v12.DeleteOptions) error { ret := m.ctrl.Call(m, "DeleteServiceAccount", namespace, name, options) ret0, _ := ret[0].(error) return ret0 @@ -250,6 +418,210 @@ func (mr *MockClientInterfaceMockRecorder) DeleteServiceAccount(namespace, name, return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteServiceAccount", reflect.TypeOf((*MockClientInterface)(nil).DeleteServiceAccount), namespace, name, options) } +// CreateRole mocks base method +func (m *MockClientInterface) CreateRole(arg0 *v11.Role) (*v11.Role, error) { + ret := m.ctrl.Call(m, "CreateRole", arg0) + ret0, _ := ret[0].(*v11.Role) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateRole indicates an expected call of CreateRole +func (mr *MockClientInterfaceMockRecorder) CreateRole(arg0 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateRole", reflect.TypeOf((*MockClientInterface)(nil).CreateRole), arg0) +} + +// GetRole mocks base method +func (m *MockClientInterface) GetRole(namespace, name string) (*v11.Role, error) { + ret := m.ctrl.Call(m, "GetRole", namespace, name) + ret0, _ := ret[0].(*v11.Role) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetRole indicates an expected call of GetRole +func (mr *MockClientInterfaceMockRecorder) GetRole(namespace, name interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRole", reflect.TypeOf((*MockClientInterface)(nil).GetRole), namespace, name) +} + +// UpdateRole mocks base method +func (m *MockClientInterface) UpdateRole(modified *v11.Role) (*v11.Role, error) { + ret := m.ctrl.Call(m, "UpdateRole", modified) + ret0, _ := ret[0].(*v11.Role) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateRole indicates an expected call of UpdateRole +func (mr *MockClientInterfaceMockRecorder) UpdateRole(modified interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateRole", reflect.TypeOf((*MockClientInterface)(nil).UpdateRole), modified) +} + +// DeleteRole mocks base method +func (m *MockClientInterface) DeleteRole(namespace, name string, options *v12.DeleteOptions) error { + ret := m.ctrl.Call(m, "DeleteRole", namespace, name, options) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteRole indicates an expected call of DeleteRole +func (mr *MockClientInterfaceMockRecorder) DeleteRole(namespace, name, options interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteRole", reflect.TypeOf((*MockClientInterface)(nil).DeleteRole), namespace, name, options) +} + +// CreateRoleBinding mocks base method +func (m *MockClientInterface) CreateRoleBinding(arg0 *v11.RoleBinding) (*v11.RoleBinding, error) { + ret := m.ctrl.Call(m, "CreateRoleBinding", arg0) + ret0, _ := ret[0].(*v11.RoleBinding) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateRoleBinding indicates an expected call of CreateRoleBinding +func (mr *MockClientInterfaceMockRecorder) CreateRoleBinding(arg0 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateRoleBinding", reflect.TypeOf((*MockClientInterface)(nil).CreateRoleBinding), arg0) +} + +// GetRoleBinding mocks base method +func (m *MockClientInterface) GetRoleBinding(namespace, name string) (*v11.RoleBinding, error) { + ret := m.ctrl.Call(m, "GetRoleBinding", namespace, name) + ret0, _ := ret[0].(*v11.RoleBinding) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetRoleBinding indicates an expected call of GetRoleBinding +func (mr *MockClientInterfaceMockRecorder) GetRoleBinding(namespace, name interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRoleBinding", reflect.TypeOf((*MockClientInterface)(nil).GetRoleBinding), namespace, name) +} + +// UpdateRoleBinding mocks base method +func (m *MockClientInterface) UpdateRoleBinding(modified *v11.RoleBinding) (*v11.RoleBinding, error) { + ret := m.ctrl.Call(m, "UpdateRoleBinding", modified) + ret0, _ := ret[0].(*v11.RoleBinding) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateRoleBinding indicates an expected call of UpdateRoleBinding +func (mr *MockClientInterfaceMockRecorder) UpdateRoleBinding(modified interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateRoleBinding", reflect.TypeOf((*MockClientInterface)(nil).UpdateRoleBinding), modified) +} + +// DeleteRoleBinding mocks base method +func (m *MockClientInterface) DeleteRoleBinding(namespace, name string, options *v12.DeleteOptions) error { + ret := m.ctrl.Call(m, "DeleteRoleBinding", namespace, name, options) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteRoleBinding indicates an expected call of DeleteRoleBinding +func (mr *MockClientInterfaceMockRecorder) DeleteRoleBinding(namespace, name, options interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteRoleBinding", reflect.TypeOf((*MockClientInterface)(nil).DeleteRoleBinding), namespace, name, options) +} + +// CreateClusterRoleBinding mocks base method +func (m *MockClientInterface) CreateClusterRoleBinding(arg0 *v11.ClusterRoleBinding) (*v11.ClusterRoleBinding, error) { + ret := m.ctrl.Call(m, "CreateClusterRoleBinding", arg0) + ret0, _ := ret[0].(*v11.ClusterRoleBinding) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateClusterRoleBinding indicates an expected call of CreateClusterRoleBinding +func (mr *MockClientInterfaceMockRecorder) CreateClusterRoleBinding(arg0 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateClusterRoleBinding", reflect.TypeOf((*MockClientInterface)(nil).CreateClusterRoleBinding), arg0) +} + +// GetClusterRoleBinding mocks base method +func (m *MockClientInterface) GetClusterRoleBinding(name string) (*v11.ClusterRoleBinding, error) { + ret := m.ctrl.Call(m, "GetClusterRoleBinding", name) + ret0, _ := ret[0].(*v11.ClusterRoleBinding) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetClusterRoleBinding indicates an expected call of GetClusterRoleBinding +func (mr *MockClientInterfaceMockRecorder) GetClusterRoleBinding(name interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetClusterRoleBinding", reflect.TypeOf((*MockClientInterface)(nil).GetClusterRoleBinding), name) +} + +// UpdateClusterRoleBinding mocks base method +func (m *MockClientInterface) UpdateClusterRoleBinding(modified *v11.ClusterRoleBinding) (*v11.ClusterRoleBinding, error) { + ret := m.ctrl.Call(m, "UpdateClusterRoleBinding", modified) + ret0, _ := ret[0].(*v11.ClusterRoleBinding) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateClusterRoleBinding indicates an expected call of UpdateClusterRoleBinding +func (mr *MockClientInterfaceMockRecorder) UpdateClusterRoleBinding(modified interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateClusterRoleBinding", reflect.TypeOf((*MockClientInterface)(nil).UpdateClusterRoleBinding), modified) +} + +// DeleteClusterRoleBinding mocks base method +func (m *MockClientInterface) DeleteClusterRoleBinding(name string, options *v12.DeleteOptions) error { + ret := m.ctrl.Call(m, "DeleteClusterRoleBinding", name, options) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteClusterRoleBinding indicates an expected call of DeleteClusterRoleBinding +func (mr *MockClientInterfaceMockRecorder) DeleteClusterRoleBinding(name, options interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteClusterRoleBinding", reflect.TypeOf((*MockClientInterface)(nil).DeleteClusterRoleBinding), name, options) +} + +// CreateClusterRole mocks base method +func (m *MockClientInterface) CreateClusterRole(arg0 *v11.ClusterRole) (*v11.ClusterRole, error) { + ret := m.ctrl.Call(m, "CreateClusterRole", arg0) + ret0, _ := ret[0].(*v11.ClusterRole) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateClusterRole indicates an expected call of CreateClusterRole +func (mr *MockClientInterfaceMockRecorder) CreateClusterRole(arg0 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateClusterRole", reflect.TypeOf((*MockClientInterface)(nil).CreateClusterRole), arg0) +} + +// GetClusterRole mocks base method +func (m *MockClientInterface) GetClusterRole(name string) (*v11.ClusterRole, error) { + ret := m.ctrl.Call(m, "GetClusterRole", name) + ret0, _ := ret[0].(*v11.ClusterRole) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetClusterRole indicates an expected call of GetClusterRole +func (mr *MockClientInterfaceMockRecorder) GetClusterRole(name interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetClusterRole", reflect.TypeOf((*MockClientInterface)(nil).GetClusterRole), name) +} + +// UpdateClusterRole mocks base method +func (m *MockClientInterface) UpdateClusterRole(modified *v11.ClusterRole) (*v11.ClusterRole, error) { + ret := m.ctrl.Call(m, "UpdateClusterRole", modified) + ret0, _ := ret[0].(*v11.ClusterRole) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateClusterRole indicates an expected call of UpdateClusterRole +func (mr *MockClientInterfaceMockRecorder) UpdateClusterRole(modified interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateClusterRole", reflect.TypeOf((*MockClientInterface)(nil).UpdateClusterRole), modified) +} + +// DeleteClusterRole mocks base method +func (m *MockClientInterface) DeleteClusterRole(name string, options *v12.DeleteOptions) error { + ret := m.ctrl.Call(m, "DeleteClusterRole", name, options) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteClusterRole indicates an expected call of DeleteClusterRole +func (mr *MockClientInterfaceMockRecorder) DeleteClusterRole(name, options interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteClusterRole", reflect.TypeOf((*MockClientInterface)(nil).DeleteClusterRole), name, options) +} + // GetDeployment mocks base method func (m *MockClientInterface) GetDeployment(namespace, name string) (*v1.Deployment, error) { ret := m.ctrl.Call(m, "GetDeployment", namespace, name) @@ -277,7 +649,7 @@ func (mr *MockClientInterfaceMockRecorder) CreateDeployment(arg0 interface{}) *g } // DeleteDeployment mocks base method -func (m *MockClientInterface) DeleteDeployment(namespace, name string, options *v11.DeleteOptions) error { +func (m *MockClientInterface) DeleteDeployment(namespace, name string, options *v12.DeleteOptions) error { ret := m.ctrl.Call(m, "DeleteDeployment", namespace, name, options) ret0, _ := ret[0].(error) return ret0 @@ -558,6 +930,228 @@ func (mr *MockCustomResourceClientMockRecorder) ListCustomResource(apiGroup, ver return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListCustomResource", reflect.TypeOf((*MockCustomResourceClient)(nil).ListCustomResource), apiGroup, version, namespace, resourceKind) } +// MockAPIServiceClient is a mock of APIServiceClient interface +type MockAPIServiceClient struct { + ctrl *gomock.Controller + recorder *MockAPIServiceClientMockRecorder +} + +// MockAPIServiceClientMockRecorder is the mock recorder for MockAPIServiceClient +type MockAPIServiceClientMockRecorder struct { + mock *MockAPIServiceClient +} + +// NewMockAPIServiceClient creates a new mock instance +func NewMockAPIServiceClient(ctrl *gomock.Controller) *MockAPIServiceClient { + mock := &MockAPIServiceClient{ctrl: ctrl} + mock.recorder = &MockAPIServiceClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockAPIServiceClient) EXPECT() *MockAPIServiceClientMockRecorder { + return m.recorder +} + +// CreateAPIService mocks base method +func (m *MockAPIServiceClient) CreateAPIService(arg0 *v13.APIService) (*v13.APIService, error) { + ret := m.ctrl.Call(m, "CreateAPIService", arg0) + ret0, _ := ret[0].(*v13.APIService) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateAPIService indicates an expected call of CreateAPIService +func (mr *MockAPIServiceClientMockRecorder) CreateAPIService(arg0 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateAPIService", reflect.TypeOf((*MockAPIServiceClient)(nil).CreateAPIService), arg0) +} + +// GetAPIService mocks base method +func (m *MockAPIServiceClient) GetAPIService(name string) (*v13.APIService, error) { + ret := m.ctrl.Call(m, "GetAPIService", name) + ret0, _ := ret[0].(*v13.APIService) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetAPIService indicates an expected call of GetAPIService +func (mr *MockAPIServiceClientMockRecorder) GetAPIService(name interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAPIService", reflect.TypeOf((*MockAPIServiceClient)(nil).GetAPIService), name) +} + +// UpdateAPIService mocks base method +func (m *MockAPIServiceClient) UpdateAPIService(modified *v13.APIService) (*v13.APIService, error) { + ret := m.ctrl.Call(m, "UpdateAPIService", modified) + ret0, _ := ret[0].(*v13.APIService) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateAPIService indicates an expected call of UpdateAPIService +func (mr *MockAPIServiceClientMockRecorder) UpdateAPIService(modified interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateAPIService", reflect.TypeOf((*MockAPIServiceClient)(nil).UpdateAPIService), modified) +} + +// DeleteAPIService mocks base method +func (m *MockAPIServiceClient) DeleteAPIService(name string, options *v12.DeleteOptions) error { + ret := m.ctrl.Call(m, "DeleteAPIService", name, options) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteAPIService indicates an expected call of DeleteAPIService +func (mr *MockAPIServiceClientMockRecorder) DeleteAPIService(name, options interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteAPIService", reflect.TypeOf((*MockAPIServiceClient)(nil).DeleteAPIService), name, options) +} + +// MockSecretClient is a mock of SecretClient interface +type MockSecretClient struct { + ctrl *gomock.Controller + recorder *MockSecretClientMockRecorder +} + +// MockSecretClientMockRecorder is the mock recorder for MockSecretClient +type MockSecretClientMockRecorder struct { + mock *MockSecretClient +} + +// NewMockSecretClient creates a new mock instance +func NewMockSecretClient(ctrl *gomock.Controller) *MockSecretClient { + mock := &MockSecretClient{ctrl: ctrl} + mock.recorder = &MockSecretClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockSecretClient) EXPECT() *MockSecretClientMockRecorder { + return m.recorder +} + +// CreateSecret mocks base method +func (m *MockSecretClient) CreateSecret(arg0 *v10.Secret) (*v10.Secret, error) { + ret := m.ctrl.Call(m, "CreateSecret", arg0) + ret0, _ := ret[0].(*v10.Secret) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateSecret indicates an expected call of CreateSecret +func (mr *MockSecretClientMockRecorder) CreateSecret(arg0 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateSecret", reflect.TypeOf((*MockSecretClient)(nil).CreateSecret), arg0) +} + +// GetSecret mocks base method +func (m *MockSecretClient) GetSecret(namespace, name string) (*v10.Secret, error) { + ret := m.ctrl.Call(m, "GetSecret", namespace, name) + ret0, _ := ret[0].(*v10.Secret) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSecret indicates an expected call of GetSecret +func (mr *MockSecretClientMockRecorder) GetSecret(namespace, name interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSecret", reflect.TypeOf((*MockSecretClient)(nil).GetSecret), namespace, name) +} + +// UpdateSecret mocks base method +func (m *MockSecretClient) UpdateSecret(modified *v10.Secret) (*v10.Secret, error) { + ret := m.ctrl.Call(m, "UpdateSecret", modified) + ret0, _ := ret[0].(*v10.Secret) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateSecret indicates an expected call of UpdateSecret +func (mr *MockSecretClientMockRecorder) UpdateSecret(modified interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateSecret", reflect.TypeOf((*MockSecretClient)(nil).UpdateSecret), modified) +} + +// DeleteSecret mocks base method +func (m *MockSecretClient) DeleteSecret(namespace, name string, options *v12.DeleteOptions) error { + ret := m.ctrl.Call(m, "DeleteSecret", namespace, name, options) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteSecret indicates an expected call of DeleteSecret +func (mr *MockSecretClientMockRecorder) DeleteSecret(namespace, name, options interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteSecret", reflect.TypeOf((*MockSecretClient)(nil).DeleteSecret), namespace, name, options) +} + +// MockServiceClient is a mock of ServiceClient interface +type MockServiceClient struct { + ctrl *gomock.Controller + recorder *MockServiceClientMockRecorder +} + +// MockServiceClientMockRecorder is the mock recorder for MockServiceClient +type MockServiceClientMockRecorder struct { + mock *MockServiceClient +} + +// NewMockServiceClient creates a new mock instance +func NewMockServiceClient(ctrl *gomock.Controller) *MockServiceClient { + mock := &MockServiceClient{ctrl: ctrl} + mock.recorder = &MockServiceClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockServiceClient) EXPECT() *MockServiceClientMockRecorder { + return m.recorder +} + +// CreateService mocks base method +func (m *MockServiceClient) CreateService(arg0 *v10.Service) (*v10.Service, error) { + ret := m.ctrl.Call(m, "CreateService", arg0) + ret0, _ := ret[0].(*v10.Service) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateService indicates an expected call of CreateService +func (mr *MockServiceClientMockRecorder) CreateService(arg0 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateService", reflect.TypeOf((*MockServiceClient)(nil).CreateService), arg0) +} + +// GetService mocks base method +func (m *MockServiceClient) GetService(namespace, name string) (*v10.Service, error) { + ret := m.ctrl.Call(m, "GetService", namespace, name) + ret0, _ := ret[0].(*v10.Service) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetService indicates an expected call of GetService +func (mr *MockServiceClientMockRecorder) GetService(namespace, name interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetService", reflect.TypeOf((*MockServiceClient)(nil).GetService), namespace, name) +} + +// UpdateService mocks base method +func (m *MockServiceClient) UpdateService(modified *v10.Service) (*v10.Service, error) { + ret := m.ctrl.Call(m, "UpdateService", modified) + ret0, _ := ret[0].(*v10.Service) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateService indicates an expected call of UpdateService +func (mr *MockServiceClientMockRecorder) UpdateService(modified interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateService", reflect.TypeOf((*MockServiceClient)(nil).UpdateService), modified) +} + +// DeleteService mocks base method +func (m *MockServiceClient) DeleteService(namespace, name string, options *v12.DeleteOptions) error { + ret := m.ctrl.Call(m, "DeleteService", namespace, name, options) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteService indicates an expected call of DeleteService +func (mr *MockServiceClientMockRecorder) DeleteService(namespace, name, options interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteService", reflect.TypeOf((*MockServiceClient)(nil).DeleteService), namespace, name, options) +} + // MockServiceAccountClient is a mock of ServiceAccountClient interface type MockServiceAccountClient struct { ctrl *gomock.Controller @@ -621,7 +1215,7 @@ func (mr *MockServiceAccountClientMockRecorder) UpdateServiceAccount(modified in } // DeleteServiceAccount mocks base method -func (m *MockServiceAccountClient) DeleteServiceAccount(namespace, name string, options *v11.DeleteOptions) error { +func (m *MockServiceAccountClient) DeleteServiceAccount(namespace, name string, options *v12.DeleteOptions) error { ret := m.ctrl.Call(m, "DeleteServiceAccount", namespace, name, options) ret0, _ := ret[0].(error) return ret0 @@ -632,6 +1226,302 @@ func (mr *MockServiceAccountClientMockRecorder) DeleteServiceAccount(namespace, return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteServiceAccount", reflect.TypeOf((*MockServiceAccountClient)(nil).DeleteServiceAccount), namespace, name, options) } +// MockRoleClient is a mock of RoleClient interface +type MockRoleClient struct { + ctrl *gomock.Controller + recorder *MockRoleClientMockRecorder +} + +// MockRoleClientMockRecorder is the mock recorder for MockRoleClient +type MockRoleClientMockRecorder struct { + mock *MockRoleClient +} + +// NewMockRoleClient creates a new mock instance +func NewMockRoleClient(ctrl *gomock.Controller) *MockRoleClient { + mock := &MockRoleClient{ctrl: ctrl} + mock.recorder = &MockRoleClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockRoleClient) EXPECT() *MockRoleClientMockRecorder { + return m.recorder +} + +// CreateRole mocks base method +func (m *MockRoleClient) CreateRole(arg0 *v11.Role) (*v11.Role, error) { + ret := m.ctrl.Call(m, "CreateRole", arg0) + ret0, _ := ret[0].(*v11.Role) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateRole indicates an expected call of CreateRole +func (mr *MockRoleClientMockRecorder) CreateRole(arg0 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateRole", reflect.TypeOf((*MockRoleClient)(nil).CreateRole), arg0) +} + +// GetRole mocks base method +func (m *MockRoleClient) GetRole(namespace, name string) (*v11.Role, error) { + ret := m.ctrl.Call(m, "GetRole", namespace, name) + ret0, _ := ret[0].(*v11.Role) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetRole indicates an expected call of GetRole +func (mr *MockRoleClientMockRecorder) GetRole(namespace, name interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRole", reflect.TypeOf((*MockRoleClient)(nil).GetRole), namespace, name) +} + +// UpdateRole mocks base method +func (m *MockRoleClient) UpdateRole(modified *v11.Role) (*v11.Role, error) { + ret := m.ctrl.Call(m, "UpdateRole", modified) + ret0, _ := ret[0].(*v11.Role) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateRole indicates an expected call of UpdateRole +func (mr *MockRoleClientMockRecorder) UpdateRole(modified interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateRole", reflect.TypeOf((*MockRoleClient)(nil).UpdateRole), modified) +} + +// DeleteRole mocks base method +func (m *MockRoleClient) DeleteRole(namespace, name string, options *v12.DeleteOptions) error { + ret := m.ctrl.Call(m, "DeleteRole", namespace, name, options) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteRole indicates an expected call of DeleteRole +func (mr *MockRoleClientMockRecorder) DeleteRole(namespace, name, options interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteRole", reflect.TypeOf((*MockRoleClient)(nil).DeleteRole), namespace, name, options) +} + +// MockRoleBindingClient is a mock of RoleBindingClient interface +type MockRoleBindingClient struct { + ctrl *gomock.Controller + recorder *MockRoleBindingClientMockRecorder +} + +// MockRoleBindingClientMockRecorder is the mock recorder for MockRoleBindingClient +type MockRoleBindingClientMockRecorder struct { + mock *MockRoleBindingClient +} + +// NewMockRoleBindingClient creates a new mock instance +func NewMockRoleBindingClient(ctrl *gomock.Controller) *MockRoleBindingClient { + mock := &MockRoleBindingClient{ctrl: ctrl} + mock.recorder = &MockRoleBindingClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockRoleBindingClient) EXPECT() *MockRoleBindingClientMockRecorder { + return m.recorder +} + +// CreateRoleBinding mocks base method +func (m *MockRoleBindingClient) CreateRoleBinding(arg0 *v11.RoleBinding) (*v11.RoleBinding, error) { + ret := m.ctrl.Call(m, "CreateRoleBinding", arg0) + ret0, _ := ret[0].(*v11.RoleBinding) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateRoleBinding indicates an expected call of CreateRoleBinding +func (mr *MockRoleBindingClientMockRecorder) CreateRoleBinding(arg0 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateRoleBinding", reflect.TypeOf((*MockRoleBindingClient)(nil).CreateRoleBinding), arg0) +} + +// GetRoleBinding mocks base method +func (m *MockRoleBindingClient) GetRoleBinding(namespace, name string) (*v11.RoleBinding, error) { + ret := m.ctrl.Call(m, "GetRoleBinding", namespace, name) + ret0, _ := ret[0].(*v11.RoleBinding) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetRoleBinding indicates an expected call of GetRoleBinding +func (mr *MockRoleBindingClientMockRecorder) GetRoleBinding(namespace, name interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRoleBinding", reflect.TypeOf((*MockRoleBindingClient)(nil).GetRoleBinding), namespace, name) +} + +// UpdateRoleBinding mocks base method +func (m *MockRoleBindingClient) UpdateRoleBinding(modified *v11.RoleBinding) (*v11.RoleBinding, error) { + ret := m.ctrl.Call(m, "UpdateRoleBinding", modified) + ret0, _ := ret[0].(*v11.RoleBinding) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateRoleBinding indicates an expected call of UpdateRoleBinding +func (mr *MockRoleBindingClientMockRecorder) UpdateRoleBinding(modified interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateRoleBinding", reflect.TypeOf((*MockRoleBindingClient)(nil).UpdateRoleBinding), modified) +} + +// DeleteRoleBinding mocks base method +func (m *MockRoleBindingClient) DeleteRoleBinding(namespace, name string, options *v12.DeleteOptions) error { + ret := m.ctrl.Call(m, "DeleteRoleBinding", namespace, name, options) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteRoleBinding indicates an expected call of DeleteRoleBinding +func (mr *MockRoleBindingClientMockRecorder) DeleteRoleBinding(namespace, name, options interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteRoleBinding", reflect.TypeOf((*MockRoleBindingClient)(nil).DeleteRoleBinding), namespace, name, options) +} + +// MockClusterRoleClient is a mock of ClusterRoleClient interface +type MockClusterRoleClient struct { + ctrl *gomock.Controller + recorder *MockClusterRoleClientMockRecorder +} + +// MockClusterRoleClientMockRecorder is the mock recorder for MockClusterRoleClient +type MockClusterRoleClientMockRecorder struct { + mock *MockClusterRoleClient +} + +// NewMockClusterRoleClient creates a new mock instance +func NewMockClusterRoleClient(ctrl *gomock.Controller) *MockClusterRoleClient { + mock := &MockClusterRoleClient{ctrl: ctrl} + mock.recorder = &MockClusterRoleClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockClusterRoleClient) EXPECT() *MockClusterRoleClientMockRecorder { + return m.recorder +} + +// CreateClusterRole mocks base method +func (m *MockClusterRoleClient) CreateClusterRole(arg0 *v11.ClusterRole) (*v11.ClusterRole, error) { + ret := m.ctrl.Call(m, "CreateClusterRole", arg0) + ret0, _ := ret[0].(*v11.ClusterRole) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateClusterRole indicates an expected call of CreateClusterRole +func (mr *MockClusterRoleClientMockRecorder) CreateClusterRole(arg0 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateClusterRole", reflect.TypeOf((*MockClusterRoleClient)(nil).CreateClusterRole), arg0) +} + +// GetClusterRole mocks base method +func (m *MockClusterRoleClient) GetClusterRole(name string) (*v11.ClusterRole, error) { + ret := m.ctrl.Call(m, "GetClusterRole", name) + ret0, _ := ret[0].(*v11.ClusterRole) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetClusterRole indicates an expected call of GetClusterRole +func (mr *MockClusterRoleClientMockRecorder) GetClusterRole(name interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetClusterRole", reflect.TypeOf((*MockClusterRoleClient)(nil).GetClusterRole), name) +} + +// UpdateClusterRole mocks base method +func (m *MockClusterRoleClient) UpdateClusterRole(modified *v11.ClusterRole) (*v11.ClusterRole, error) { + ret := m.ctrl.Call(m, "UpdateClusterRole", modified) + ret0, _ := ret[0].(*v11.ClusterRole) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateClusterRole indicates an expected call of UpdateClusterRole +func (mr *MockClusterRoleClientMockRecorder) UpdateClusterRole(modified interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateClusterRole", reflect.TypeOf((*MockClusterRoleClient)(nil).UpdateClusterRole), modified) +} + +// DeleteClusterRole mocks base method +func (m *MockClusterRoleClient) DeleteClusterRole(name string, options *v12.DeleteOptions) error { + ret := m.ctrl.Call(m, "DeleteClusterRole", name, options) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteClusterRole indicates an expected call of DeleteClusterRole +func (mr *MockClusterRoleClientMockRecorder) DeleteClusterRole(name, options interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteClusterRole", reflect.TypeOf((*MockClusterRoleClient)(nil).DeleteClusterRole), name, options) +} + +// MockClusterRoleBindingClient is a mock of ClusterRoleBindingClient interface +type MockClusterRoleBindingClient struct { + ctrl *gomock.Controller + recorder *MockClusterRoleBindingClientMockRecorder +} + +// MockClusterRoleBindingClientMockRecorder is the mock recorder for MockClusterRoleBindingClient +type MockClusterRoleBindingClientMockRecorder struct { + mock *MockClusterRoleBindingClient +} + +// NewMockClusterRoleBindingClient creates a new mock instance +func NewMockClusterRoleBindingClient(ctrl *gomock.Controller) *MockClusterRoleBindingClient { + mock := &MockClusterRoleBindingClient{ctrl: ctrl} + mock.recorder = &MockClusterRoleBindingClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockClusterRoleBindingClient) EXPECT() *MockClusterRoleBindingClientMockRecorder { + return m.recorder +} + +// CreateClusterRoleBinding mocks base method +func (m *MockClusterRoleBindingClient) CreateClusterRoleBinding(arg0 *v11.ClusterRoleBinding) (*v11.ClusterRoleBinding, error) { + ret := m.ctrl.Call(m, "CreateClusterRoleBinding", arg0) + ret0, _ := ret[0].(*v11.ClusterRoleBinding) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateClusterRoleBinding indicates an expected call of CreateClusterRoleBinding +func (mr *MockClusterRoleBindingClientMockRecorder) CreateClusterRoleBinding(arg0 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateClusterRoleBinding", reflect.TypeOf((*MockClusterRoleBindingClient)(nil).CreateClusterRoleBinding), arg0) +} + +// GetClusterRoleBinding mocks base method +func (m *MockClusterRoleBindingClient) GetClusterRoleBinding(name string) (*v11.ClusterRoleBinding, error) { + ret := m.ctrl.Call(m, "GetClusterRoleBinding", name) + ret0, _ := ret[0].(*v11.ClusterRoleBinding) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetClusterRoleBinding indicates an expected call of GetClusterRoleBinding +func (mr *MockClusterRoleBindingClientMockRecorder) GetClusterRoleBinding(name interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetClusterRoleBinding", reflect.TypeOf((*MockClusterRoleBindingClient)(nil).GetClusterRoleBinding), name) +} + +// UpdateClusterRoleBinding mocks base method +func (m *MockClusterRoleBindingClient) UpdateClusterRoleBinding(modified *v11.ClusterRoleBinding) (*v11.ClusterRoleBinding, error) { + ret := m.ctrl.Call(m, "UpdateClusterRoleBinding", modified) + ret0, _ := ret[0].(*v11.ClusterRoleBinding) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateClusterRoleBinding indicates an expected call of UpdateClusterRoleBinding +func (mr *MockClusterRoleBindingClientMockRecorder) UpdateClusterRoleBinding(modified interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateClusterRoleBinding", reflect.TypeOf((*MockClusterRoleBindingClient)(nil).UpdateClusterRoleBinding), modified) +} + +// DeleteClusterRoleBinding mocks base method +func (m *MockClusterRoleBindingClient) DeleteClusterRoleBinding(name string, options *v12.DeleteOptions) error { + ret := m.ctrl.Call(m, "DeleteClusterRoleBinding", name, options) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteClusterRoleBinding indicates an expected call of DeleteClusterRoleBinding +func (mr *MockClusterRoleBindingClientMockRecorder) DeleteClusterRoleBinding(name, options interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteClusterRoleBinding", reflect.TypeOf((*MockClusterRoleBindingClient)(nil).DeleteClusterRoleBinding), name, options) +} + // MockDeploymentClient is a mock of DeploymentClient interface type MockDeploymentClient struct { ctrl *gomock.Controller @@ -682,7 +1572,7 @@ func (mr *MockDeploymentClientMockRecorder) CreateDeployment(arg0 interface{}) * } // DeleteDeployment mocks base method -func (m *MockDeploymentClient) DeleteDeployment(namespace, name string, options *v11.DeleteOptions) error { +func (m *MockDeploymentClient) DeleteDeployment(namespace, name string, options *v12.DeleteOptions) error { ret := m.ctrl.Call(m, "DeleteDeployment", namespace, name, options) ret0, _ := ret[0].(error) return ret0 diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient/patch.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient/patch.go index 57122feab5..6c9881fc2b 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient/patch.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient/patch.go @@ -5,7 +5,7 @@ import ( "fmt" appsv1 "k8s.io/api/apps/v1" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" extensionsv1beta1 "k8s.io/api/extensions/v1beta1" v1beta1ext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" "k8s.io/apimachinery/pkg/api/meta" diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient/role.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient/role.go new file mode 100755 index 0000000000..fc07d73ace --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient/role.go @@ -0,0 +1,39 @@ +package operatorclient + +import ( + "fmt" + + "github.com/golang/glog" + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" +) + +// CreateRole creates the role. +func (c *Client) CreateRole(r *rbacv1.Role) (*rbacv1.Role, error) { + return c.RbacV1().Roles(r.GetNamespace()).Create(r) +} + +// GetRole returns the existing role. +func (c *Client) GetRole(namespace, name string) (*rbacv1.Role, error) { + return c.RbacV1().Roles(namespace).Get(name, metav1.GetOptions{}) +} + +// DeleteRole deletes the role. +func (c *Client) DeleteRole(namespace, name string, options *metav1.DeleteOptions) error { + return c.RbacV1().Roles(namespace).Delete(name, options) +} + +// UpdateRole will update the given Role resource. +func (c *Client) UpdateRole(crb *rbacv1.Role) (*rbacv1.Role, error) { + glog.V(4).Infof("[UPDATE Role]: %s", crb.GetName()) + oldCrb, err := c.GetRole(crb.GetNamespace(), crb.GetName()) + if err != nil { + return nil, err + } + patchBytes, err := createPatch(oldCrb, crb) + if err != nil { + return nil, fmt.Errorf("error creating patch for Role: %v", err) + } + return c.RbacV1().Roles(crb.GetNamespace()).Patch(crb.GetName(), types.StrategicMergePatchType, patchBytes) +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient/rolebinding.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient/rolebinding.go new file mode 100755 index 0000000000..e9d084e851 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient/rolebinding.go @@ -0,0 +1,39 @@ +package operatorclient + +import ( + "fmt" + + "github.com/golang/glog" + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" +) + +// CreateRoleBinding creates the roleBinding. +func (c *Client) CreateRoleBinding(ig *rbacv1.RoleBinding) (*rbacv1.RoleBinding, error) { + return c.RbacV1().RoleBindings(ig.GetNamespace()).Create(ig) +} + +// GetRoleBinding returns the existing roleBinding. +func (c *Client) GetRoleBinding(namespace, name string) (*rbacv1.RoleBinding, error) { + return c.RbacV1().RoleBindings(namespace).Get(name, metav1.GetOptions{}) +} + +// DeleteRoleBinding deletes the roleBinding. +func (c *Client) DeleteRoleBinding(namespace, name string, options *metav1.DeleteOptions) error { + return c.RbacV1().RoleBindings(namespace).Delete(name, options) +} + +// UpdateRoleBinding will update the given RoleBinding resource. +func (c *Client) UpdateRoleBinding(crb *rbacv1.RoleBinding) (*rbacv1.RoleBinding, error) { + glog.V(4).Infof("[UPDATE RoleBinding]: %s", crb.GetName()) + oldCrb, err := c.GetRoleBinding(crb.GetNamespace(), crb.GetName()) + if err != nil { + return nil, err + } + patchBytes, err := createPatch(oldCrb, crb) + if err != nil { + return nil, fmt.Errorf("error creating patch for RoleBinding: %v", err) + } + return c.RbacV1().RoleBindings(crb.GetNamespace()).Patch(crb.GetName(), types.StrategicMergePatchType, patchBytes) +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient/secret.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient/secret.go new file mode 100644 index 0000000000..e20d3d8b6f --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient/secret.go @@ -0,0 +1,39 @@ +package operatorclient + +import ( + "fmt" + + "github.com/golang/glog" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" +) + +// CreateSecret creates the Secret. +func (c *Client) CreateSecret(ig *v1.Secret) (*v1.Secret, error) { + return c.CoreV1().Secrets(ig.GetNamespace()).Create(ig) +} + +// GetSecret returns the existing Secret. +func (c *Client) GetSecret(namespace, name string) (*v1.Secret, error) { + return c.CoreV1().Secrets(namespace).Get(name, metav1.GetOptions{}) +} + +// DeleteSecret deletes the Secret. +func (c *Client) DeleteSecret(namespace, name string, options *metav1.DeleteOptions) error { + return c.CoreV1().Secrets(namespace).Delete(name, options) +} + +// UpdateSecret will update the given Secret resource. +func (c *Client) UpdateSecret(secret *v1.Secret) (*v1.Secret, error) { + glog.V(4).Infof("[UPDATE Secret]: %s", secret.GetName()) + oldSa, err := c.GetSecret(secret.GetNamespace(), secret.GetName()) + if err != nil { + return nil, err + } + patchBytes, err := createPatch(oldSa, secret) + if err != nil { + return nil, fmt.Errorf("error creating patch for Secret: %v", err) + } + return c.CoreV1().Secrets(secret.GetNamespace()).Patch(secret.GetName(), types.StrategicMergePatchType, patchBytes) +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient/service.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient/service.go new file mode 100644 index 0000000000..4491233d78 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient/service.go @@ -0,0 +1,39 @@ +package operatorclient + +import ( + "fmt" + + "github.com/golang/glog" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" +) + +// CreateService creates the Service. +func (c *Client) CreateService(ig *v1.Service) (*v1.Service, error) { + return c.CoreV1().Services(ig.GetNamespace()).Create(ig) +} + +// GetService returns the existing Service. +func (c *Client) GetService(namespace, name string) (*v1.Service, error) { + return c.CoreV1().Services(namespace).Get(name, metav1.GetOptions{}) +} + +// DeleteService deletes the Service. +func (c *Client) DeleteService(namespace, name string, options *metav1.DeleteOptions) error { + return c.CoreV1().Services(namespace).Delete(name, options) +} + +// UpdateService will update the given Service resource. +func (c *Client) UpdateService(service *v1.Service) (*v1.Service, error) { + glog.V(4).Infof("[UPDATE Service]: %s", service.GetName()) + oldSa, err := c.GetService(service.GetNamespace(), service.GetName()) + if err != nil { + return nil, err + } + patchBytes, err := createPatch(oldSa, service) + if err != nil { + return nil, fmt.Errorf("error creating patch for Service: %v", err) + } + return c.CoreV1().Services(service.GetNamespace()).Patch(service.GetName(), types.StrategicMergePatchType, patchBytes) +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient/serviceaccount.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient/serviceaccount.go index b157596530..4e6591d5b2 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient/serviceaccount.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient/serviceaccount.go @@ -4,7 +4,7 @@ import ( "fmt" "github.com/golang/glog" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" ) diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/apiservice.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/apiservice.go new file mode 100644 index 0000000000..5de0879c2a --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/apiservice.go @@ -0,0 +1,55 @@ +package operatorlister + +import ( + "fmt" + "sync" + + "k8s.io/apimachinery/pkg/labels" + v1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" + aregv1 "k8s.io/kube-aggregator/pkg/client/listers/apiregistration/v1" +) + +// UnionAPIServiceLister is a custom implementation of an APIService lister that allows a new +// Lister to be registered on the fly +type UnionAPIServiceLister struct { + apiServiceLister aregv1.APIServiceLister + apiServiceLock sync.RWMutex +} + +// List lists all APIServices in the indexer. +func (ual *UnionAPIServiceLister) List(selector labels.Selector) (ret []*v1.APIService, err error) { + ual.apiServiceLock.RLock() + defer ual.apiServiceLock.RUnlock() + + if ual.apiServiceLister == nil { + return nil, fmt.Errorf("no apiService lister registered") + } + return ual.apiServiceLister.List(selector) +} + +// Get retrieves the APIService with the given name +func (ual *UnionAPIServiceLister) Get(name string) (*v1.APIService, error) { + ual.apiServiceLock.RLock() + defer ual.apiServiceLock.RUnlock() + + if ual.apiServiceLister == nil { + return nil, fmt.Errorf("no apiService lister registered") + } + return ual.apiServiceLister.Get(name) +} + +// RegisterAPIServiceLister registers a new APIServiceLister +func (ual *UnionAPIServiceLister) RegisterAPIServiceLister(lister aregv1.APIServiceLister) { + ual.apiServiceLock.Lock() + defer ual.apiServiceLock.Unlock() + + ual.apiServiceLister = lister +} + +func (l *apiRegistrationV1Lister) RegisterAPIServiceLister(lister aregv1.APIServiceLister) { + l.apiServiceLister.RegisterAPIServiceLister(lister) +} + +func (l *apiRegistrationV1Lister) APIServiceLister() aregv1.APIServiceLister { + return l.apiServiceLister +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/clusterrole.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/clusterrole.go new file mode 100644 index 0000000000..174ffa1da4 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/clusterrole.go @@ -0,0 +1,51 @@ +package operatorlister + +import ( + "fmt" + "sync" + + v1 "k8s.io/api/rbac/v1" + "k8s.io/apimachinery/pkg/labels" + rbacv1 "k8s.io/client-go/listers/rbac/v1" +) + +type UnionClusterRoleLister struct { + clusterRoleLister rbacv1.ClusterRoleLister + clusterRoleLock sync.RWMutex +} + +// List lists all ClusterRoles in the indexer. +func (ucl *UnionClusterRoleLister) List(selector labels.Selector) (ret []*v1.ClusterRole, err error) { + ucl.clusterRoleLock.RLock() + defer ucl.clusterRoleLock.RUnlock() + + if ucl.clusterRoleLister == nil { + return nil, fmt.Errorf("no clusterRole lister registered") + } + return ucl.clusterRoleLister.List(selector) +} + +func (ucl *UnionClusterRoleLister) Get(name string) (*v1.ClusterRole, error) { + ucl.clusterRoleLock.RLock() + defer ucl.clusterRoleLock.RUnlock() + + if ucl.clusterRoleLister == nil { + return nil, fmt.Errorf("no clusterRole lister registered") + } + return ucl.clusterRoleLister.Get(name) +} + +func (ucl *UnionClusterRoleLister) RegisterClusterRoleLister(lister rbacv1.ClusterRoleLister) { + ucl.clusterRoleLock.Lock() + defer ucl.clusterRoleLock.Unlock() + + ucl.clusterRoleLister = lister +} + +func (l *rbacV1Lister) RegisterClusterRoleLister(lister rbacv1.ClusterRoleLister) { + l.clusterRoleLister.RegisterClusterRoleLister(lister) +} + +func (l *rbacV1Lister) ClusterRoleLister() rbacv1.ClusterRoleLister { + return l.clusterRoleLister +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/clusterrolebinding.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/clusterrolebinding.go new file mode 100644 index 0000000000..c0ed5c7445 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/clusterrolebinding.go @@ -0,0 +1,51 @@ +package operatorlister + +import ( + "fmt" + "sync" + + v1 "k8s.io/api/rbac/v1" + "k8s.io/apimachinery/pkg/labels" + rbacv1 "k8s.io/client-go/listers/rbac/v1" +) + +type UnionClusterRoleBindingLister struct { + clusterRoleBindingLister rbacv1.ClusterRoleBindingLister + clusterRoleBindingLock sync.RWMutex +} + +// List lists all ClusterRoleBindings in the indexer. +func (ucl *UnionClusterRoleBindingLister) List(selector labels.Selector) (ret []*v1.ClusterRoleBinding, err error) { + ucl.clusterRoleBindingLock.RLock() + defer ucl.clusterRoleBindingLock.RUnlock() + + if ucl.clusterRoleBindingLister == nil { + return nil, fmt.Errorf("no clusterRoleBinding lister registered") + } + return ucl.clusterRoleBindingLister.List(selector) +} + +func (ucl *UnionClusterRoleBindingLister) Get(name string) (*v1.ClusterRoleBinding, error) { + ucl.clusterRoleBindingLock.RLock() + defer ucl.clusterRoleBindingLock.RUnlock() + + if ucl.clusterRoleBindingLister == nil { + return nil, fmt.Errorf("no clusterRoleBinding lister registered") + } + return ucl.clusterRoleBindingLister.Get(name) +} + +func (ucl *UnionClusterRoleBindingLister) RegisterClusterRoleBindingLister(lister rbacv1.ClusterRoleBindingLister) { + ucl.clusterRoleBindingLock.Lock() + defer ucl.clusterRoleBindingLock.Unlock() + + ucl.clusterRoleBindingLister = lister +} + +func (l *rbacV1Lister) RegisterClusterRoleBindingLister(lister rbacv1.ClusterRoleBindingLister) { + l.clusterRoleBindingLister.RegisterClusterRoleBindingLister(lister) +} + +func (l *rbacV1Lister) ClusterRoleBindingLister() rbacv1.ClusterRoleBindingLister { + return l.clusterRoleBindingLister +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/clusterserviceversion.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/clusterserviceversion.go new file mode 100644 index 0000000000..a0f99ce000 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/clusterserviceversion.go @@ -0,0 +1,96 @@ +package operatorlister + +import ( + "fmt" + "sync" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/types" + + "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + listers "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1alpha1" +) + +type UnionClusterServiceVersionLister struct { + csvListers map[string]listers.ClusterServiceVersionLister + csvLock sync.RWMutex +} + +// List lists all ClusterServiceVersions in the indexer. +func (ucl *UnionClusterServiceVersionLister) List(selector labels.Selector) (ret []*v1alpha1.ClusterServiceVersion, err error) { + ucl.csvLock.RLock() + defer ucl.csvLock.RUnlock() + + set := make(map[types.UID]*v1alpha1.ClusterServiceVersion) + for _, cl := range ucl.csvListers { + csvs, err := cl.List(selector) + if err != nil { + return nil, err + } + + for _, csv := range csvs { + set[csv.GetUID()] = csv + } + } + + for _, csv := range set { + ret = append(ret, csv) + } + + return +} + +// ClusterServiceVersions returns an object that can list and get ClusterServiceVersions. +func (ucl *UnionClusterServiceVersionLister) ClusterServiceVersions(namespace string) listers.ClusterServiceVersionNamespaceLister { + ucl.csvLock.RLock() + defer ucl.csvLock.RUnlock() + + // Check for specific namespace listers + if cl, ok := ucl.csvListers[namespace]; ok { + return cl.ClusterServiceVersions(namespace) + } + + // Check for any namespace-all listers + if cl, ok := ucl.csvListers[metav1.NamespaceAll]; ok { + return cl.ClusterServiceVersions(namespace) + } + + return &NullClusterServiceVersionNamespaceLister{} +} + +func (ucl *UnionClusterServiceVersionLister) RegisterClusterServiceVersionLister(namespace string, lister listers.ClusterServiceVersionLister) { + ucl.csvLock.Lock() + defer ucl.csvLock.Unlock() + + if ucl.csvListers == nil { + ucl.csvListers = make(map[string]listers.ClusterServiceVersionLister) + } + + ucl.csvListers[namespace] = lister +} + +func (l *operatorsV1alpha1Lister) RegisterClusterServiceVersionLister(namespace string, lister listers.ClusterServiceVersionLister) { + l.clusterServiceVersionLister.RegisterClusterServiceVersionLister(namespace, lister) +} + +func (l *operatorsV1alpha1Lister) ClusterServiceVersionLister() listers.ClusterServiceVersionLister { + return l.clusterServiceVersionLister +} + +// NullClusterServiceVersionNamespaceLister is an implementation of a null ClusterServiceVersionNamespaceLister. It is +// used to prevent nil pointers when no ClusterServiceVersionNamespaceLister has been registered for a given +// namespace. +type NullClusterServiceVersionNamespaceLister struct { + listers.ClusterServiceVersionNamespaceLister +} + +// List returns nil and an error explaining that this is a NullClusterServiceVersionNamespaceLister. +func (n *NullClusterServiceVersionNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.ClusterServiceVersion, err error) { + return nil, fmt.Errorf("cannot list ClusterServiceVersions with a NullClusterServiceVersionNamespaceLister") +} + +// Get returns nil and an error explaining that this is a NullClusterServiceVersionNamespaceLister. +func (n *NullClusterServiceVersionNamespaceLister) Get(name string) (*v1alpha1.ClusterServiceVersion, error) { + return nil, fmt.Errorf("cannot get ClusterServiceVersion with a NullClusterServiceVersionNamespaceLister") +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/configmap.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/configmap.go new file mode 100644 index 0000000000..e15132103d --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/configmap.go @@ -0,0 +1,94 @@ +package operatorlister + +import ( + "fmt" + "sync" + + "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/types" + corev1 "k8s.io/client-go/listers/core/v1" +) + +type UnionConfigMapLister struct { + configMapListers map[string]corev1.ConfigMapLister + configMapLock sync.RWMutex +} + +// List lists all ConfigMaps in the indexer. +func (usl *UnionConfigMapLister) List(selector labels.Selector) (ret []*v1.ConfigMap, err error) { + usl.configMapLock.RLock() + defer usl.configMapLock.RUnlock() + + set := make(map[types.UID]*v1.ConfigMap) + for _, sl := range usl.configMapListers { + configMaps, err := sl.List(selector) + if err != nil { + return nil, err + } + + for _, configMap := range configMaps { + set[configMap.GetUID()] = configMap + } + } + + for _, configMap := range set { + ret = append(ret, configMap) + } + + return +} + +// ConfigMaps returns an object that can list and get ConfigMaps. +func (usl *UnionConfigMapLister) ConfigMaps(namespace string) corev1.ConfigMapNamespaceLister { + usl.configMapLock.RLock() + defer usl.configMapLock.RUnlock() + + // Check for specific namespace listers + if sl, ok := usl.configMapListers[namespace]; ok { + return sl.ConfigMaps(namespace) + } + + // Check for any namespace-all listers + if sl, ok := usl.configMapListers[metav1.NamespaceAll]; ok { + return sl.ConfigMaps(namespace) + } + + return &NullConfigMapNamespaceLister{} +} + +func (usl *UnionConfigMapLister) RegisterConfigMapLister(namespace string, lister corev1.ConfigMapLister) { + usl.configMapLock.Lock() + defer usl.configMapLock.Unlock() + + if usl.configMapListers == nil { + usl.configMapListers = make(map[string]corev1.ConfigMapLister) + } + usl.configMapListers[namespace] = lister +} + +func (l *coreV1Lister) RegisterConfigMapLister(namespace string, lister corev1.ConfigMapLister) { + l.configMapLister.RegisterConfigMapLister(namespace, lister) +} + +func (l *coreV1Lister) ConfigMapLister() corev1.ConfigMapLister { + return l.configMapLister +} + +// NullConfigMapNamespaceLister is an implementation of a null ConfigMapNamespaceLister. It is +// used to prevent nil pointers when no ConfigMapNamespaceLister has been registered for a given +// namespace. +type NullConfigMapNamespaceLister struct { + corev1.ConfigMapNamespaceLister +} + +// List returns nil and an error explaining that this is a NullConfigMapNamespaceLister. +func (n *NullConfigMapNamespaceLister) List(selector labels.Selector) (ret []*v1.ConfigMap, err error) { + return nil, fmt.Errorf("cannot list ConfigMaps with a NullConfigMapNamespaceLister") +} + +// Get returns nil and an error explaining that this is a NullConfigMapNamespaceLister. +func (n *NullConfigMapNamespaceLister) Get(name string) (*v1.ConfigMap, error) { + return nil, fmt.Errorf("cannot get ConfigMap with a NullConfigMapNamespaceLister") +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/customresourcedefinition.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/customresourcedefinition.go new file mode 100644 index 0000000000..9bbc6ce192 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/customresourcedefinition.go @@ -0,0 +1,55 @@ +package operatorlister + +import ( + "fmt" + "sync" + + v1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" + aextv1beta1 "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1beta1" + "k8s.io/apimachinery/pkg/labels" +) + +// UnionCustomResourceDefinitionLister is a custom implementation of an CustomResourceDefinition lister that allows a new +// Lister to be registered on the fly +type UnionCustomResourceDefinitionLister struct { + CustomResourceDefinitionLister aextv1beta1.CustomResourceDefinitionLister + CustomResourceDefinitionLock sync.RWMutex +} + +// List lists all CustomResourceDefinitions in the indexer. +func (ucl *UnionCustomResourceDefinitionLister) List(selector labels.Selector) (ret []*v1beta1.CustomResourceDefinition, err error) { + ucl.CustomResourceDefinitionLock.RLock() + defer ucl.CustomResourceDefinitionLock.RUnlock() + + if ucl.CustomResourceDefinitionLister == nil { + return nil, fmt.Errorf("no CustomResourceDefinition lister registered") + } + return ucl.CustomResourceDefinitionLister.List(selector) +} + +// Get retrieves the CustomResourceDefinition with the given name +func (ucl *UnionCustomResourceDefinitionLister) Get(name string) (*v1beta1.CustomResourceDefinition, error) { + ucl.CustomResourceDefinitionLock.RLock() + defer ucl.CustomResourceDefinitionLock.RUnlock() + + if ucl.CustomResourceDefinitionLister == nil { + return nil, fmt.Errorf("no CustomResourceDefinition lister registered") + } + return ucl.CustomResourceDefinitionLister.Get(name) +} + +// RegisterCustomResourceDefinitionLister registers a new CustomResourceDefinitionLister +func (ucl *UnionCustomResourceDefinitionLister) RegisterCustomResourceDefinitionLister(lister aextv1beta1.CustomResourceDefinitionLister) { + ucl.CustomResourceDefinitionLock.Lock() + defer ucl.CustomResourceDefinitionLock.Unlock() + + ucl.CustomResourceDefinitionLister = lister +} + +func (l *apiExtensionsV1beta1Lister) RegisterCustomResourceDefinitionLister(lister aextv1beta1.CustomResourceDefinitionLister) { + l.customResourceDefinitionLister.RegisterCustomResourceDefinitionLister(lister) +} + +func (l *apiExtensionsV1beta1Lister) CustomResourceDefinitionLister() aextv1beta1.CustomResourceDefinitionLister { + return l.customResourceDefinitionLister +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/deployment.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/deployment.go new file mode 100644 index 0000000000..af7fea9a7f --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/deployment.go @@ -0,0 +1,117 @@ +package operatorlister + +import ( + "fmt" + "sync" + + v1 "k8s.io/api/apps/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/types" + appsv1 "k8s.io/client-go/listers/apps/v1" +) + +type UnionDeploymentLister struct { + deploymentListers map[string]appsv1.DeploymentLister + deploymentLock sync.RWMutex +} + +// List lists all Deployments in the indexer. +func (udl *UnionDeploymentLister) List(selector labels.Selector) (ret []*v1.Deployment, err error) { + udl.deploymentLock.RLock() + defer udl.deploymentLock.RUnlock() + + var set map[types.UID]*v1.Deployment + for _, dl := range udl.deploymentListers { + deployments, err := dl.List(selector) + if err != nil { + return nil, err + } + + for _, deployment := range deployments { + set[deployment.GetUID()] = deployment + } + } + + for _, deployment := range set { + ret = append(ret, deployment) + } + + return +} + +// Deployments returns an object that can list and get Deployments. +func (udl *UnionDeploymentLister) Deployments(namespace string) appsv1.DeploymentNamespaceLister { + udl.deploymentLock.RLock() + defer udl.deploymentLock.RUnlock() + + // Check for specific namespace listers + if dl, ok := udl.deploymentListers[namespace]; ok { + return dl.Deployments(namespace) + } + + // Check for any namespace-all listers + if dl, ok := udl.deploymentListers[metav1.NamespaceAll]; ok { + return dl.Deployments(namespace) + } + + return &NullDeploymentNamespaceLister{} +} + +func (udl *UnionDeploymentLister) GetDeploymentsForReplicaSet(rs *v1.ReplicaSet) ([]*v1.Deployment, error) { + udl.deploymentLock.RLock() + defer udl.deploymentLock.RUnlock() + + // Check for specific namespace listers + if dl, ok := udl.deploymentListers[rs.GetNamespace()]; ok { + return dl.GetDeploymentsForReplicaSet(rs) + } + + // Check for any namespace-all listers + if dl, ok := udl.deploymentListers[metav1.NamespaceAll]; ok { + return dl.GetDeploymentsForReplicaSet(rs) + } + + return nil, fmt.Errorf("no listers found for namespace %s", rs.GetNamespace()) +} + +func (udl *UnionDeploymentLister) RegisterDeploymentLister(namespace string, lister appsv1.DeploymentLister) { + udl.deploymentLock.Lock() + defer udl.deploymentLock.Unlock() + + if udl.deploymentListers == nil { + udl.deploymentListers = make(map[string]appsv1.DeploymentLister) + } + + udl.deploymentListers[namespace] = lister +} + +func (l *appsV1Lister) RegisterDeploymentLister(namespace string, lister appsv1.DeploymentLister) { + l.deploymentLister.RegisterDeploymentLister(namespace, lister) +} + +func (l *appsV1Lister) DeploymentLister() appsv1.DeploymentLister { + return l.deploymentLister +} + +// NullDeploymentNamespaceLister is an implementation of a null DeploymentNamespaceLister. It is +// used to prevent nil pointers when no DeploymentNamespaceLister has been registered for a given +// namespace. +type NullDeploymentNamespaceLister struct { + appsv1.DeploymentNamespaceLister +} + +// List returns nil and an error explaining that this is a NullDeploymentNamespaceLister. +func (n *NullDeploymentNamespaceLister) List(selector labels.Selector) (ret []*v1.Deployment, err error) { + return nil, fmt.Errorf("cannot list Deployments with a NullDeploymentNamespaceLister") +} + +// Get returns nil and an error explaining that this is a NullDeploymentNamespaceLister. +func (n *NullDeploymentNamespaceLister) Get(name string) (*v1.Deployment, error) { + return nil, fmt.Errorf("cannot get Deployment with a NullDeploymentNamespaceLister") +} + +// GetDeploymentsForReplicaSet returns nil and an error explaining that this is a NullDeploymentNamespaceLister +func (n *NullDeploymentNamespaceLister) GetDeploymentsForReplicaSet(rs *v1.ReplicaSet) ([]*v1.Deployment, error) { + return nil, fmt.Errorf("cannot get Deployments for a ReplicaSet with a NullDeploymentNamespaceLister") +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/installplan.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/installplan.go new file mode 100644 index 0000000000..9dad112018 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/installplan.go @@ -0,0 +1,96 @@ +package operatorlister + +import ( + "fmt" + "sync" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/types" + + "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + listers "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1alpha1" +) + +type UnionInstallPlanLister struct { + ipListers map[string]listers.InstallPlanLister + ipLock sync.RWMutex +} + +// List lists all InstallPlans in the indexer. +func (u *UnionInstallPlanLister) List(selector labels.Selector) (ret []*v1alpha1.InstallPlan, err error) { + u.ipLock.RLock() + defer u.ipLock.RUnlock() + + set := make(map[types.UID]*v1alpha1.InstallPlan) + for _, cl := range u.ipListers { + ips, err := cl.List(selector) + if err != nil { + return nil, err + } + + for _, ip := range ips { + set[ip.GetUID()] = ip + } + } + + for _, ip := range set { + ret = append(ret, ip) + } + + return +} + +// InstallPlans returns an object that can list and get InstallPlans. +func (u *UnionInstallPlanLister) InstallPlans(namespace string) listers.InstallPlanNamespaceLister { + u.ipLock.RLock() + defer u.ipLock.RUnlock() + + // Check for specific namespace listers + if cl, ok := u.ipListers[namespace]; ok { + return cl.InstallPlans(namespace) + } + + // Check for any namespace-all listers + if cl, ok := u.ipListers[metav1.NamespaceAll]; ok { + return cl.InstallPlans(namespace) + } + + return &NullInstallPlanNamespaceLister{} +} + +func (u *UnionInstallPlanLister) RegisterInstallPlanLister(namespace string, lister listers.InstallPlanLister) { + u.ipLock.Lock() + defer u.ipLock.Unlock() + + if u.ipListers == nil { + u.ipListers = make(map[string]listers.InstallPlanLister) + } + + u.ipListers[namespace] = lister +} + +func (l *operatorsV1alpha1Lister) RegisterInstallPlanLister(namespace string, lister listers.InstallPlanLister) { + l.installPlanLister.RegisterInstallPlanLister(namespace, lister) +} + +func (l *operatorsV1alpha1Lister) InstallPlanLister() listers.InstallPlanLister { + return l.installPlanLister +} + +// NullInstallPlanNamespaceLister is an implementation of a null InstallPlanNamespaceLister. It is +// used to prevent nil pointers when no InstallPlanNamespaceLister has been registered for a given +// namespace. +type NullInstallPlanNamespaceLister struct { + listers.InstallPlanNamespaceLister +} + +// List returns nil and an error explaining that this is a NullInstallPlanNamespaceLister. +func (n *NullInstallPlanNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.InstallPlan, err error) { + return nil, fmt.Errorf("cannot list InstallPlans with a NullInstallPlanNamespaceLister") +} + +// Get returns nil and an error explaining that this is a NullInstallPlanNamespaceLister. +func (n *NullInstallPlanNamespaceLister) Get(name string) (*v1alpha1.InstallPlan, error) { + return nil, fmt.Errorf("cannot get InstallPlan with a NullInstallPlanNamespaceLister") +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/lister.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/lister.go new file mode 100644 index 0000000000..22b9622487 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/lister.go @@ -0,0 +1,240 @@ +package operatorlister + +import ( + aextv1beta1 "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1beta1" + appsv1 "k8s.io/client-go/listers/apps/v1" + corev1 "k8s.io/client-go/listers/core/v1" + rbacv1 "k8s.io/client-go/listers/rbac/v1" + aregv1 "k8s.io/kube-aggregator/pkg/client/listers/apiregistration/v1" + + "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1" + "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1alpha1" +) + +// OperatorLister is a union of versioned informer listers +//go:generate counterfeiter . OperatorLister +type OperatorLister interface { + AppsV1() AppsV1Lister + CoreV1() CoreV1Lister + RbacV1() RbacV1Lister + APIRegistrationV1() APIRegistrationV1Lister + APIExtensionsV1beta1() APIExtensionsV1beta1Lister + + OperatorsV1alpha1() OperatorsV1alpha1Lister + OperatorsV1() OperatorsV1Lister +} + +//go:generate counterfeiter . AppsV1Lister +type AppsV1Lister interface { + DeploymentLister() appsv1.DeploymentLister + + RegisterDeploymentLister(namespace string, lister appsv1.DeploymentLister) +} + +//go:generate counterfeiter . CoreV1Lister +type CoreV1Lister interface { + RegisterSecretLister(namespace string, lister corev1.SecretLister) + RegisterServiceLister(namespace string, lister corev1.ServiceLister) + RegisterServiceAccountLister(namespace string, lister corev1.ServiceAccountLister) + RegisterPodLister(namespace string, lister corev1.PodLister) + RegisterConfigMapLister(namespace string, lister corev1.ConfigMapLister) + RegisterNamespaceLister(lister corev1.NamespaceLister) + + SecretLister() corev1.SecretLister + ServiceLister() corev1.ServiceLister + ServiceAccountLister() corev1.ServiceAccountLister + NamespaceLister() corev1.NamespaceLister + PodLister() corev1.PodLister + ConfigMapLister() corev1.ConfigMapLister +} + +//go:generate counterfeiter . RbacV1Lister +type RbacV1Lister interface { + RegisterClusterRoleLister(lister rbacv1.ClusterRoleLister) + RegisterClusterRoleBindingLister(lister rbacv1.ClusterRoleBindingLister) + RegisterRoleLister(namespace string, lister rbacv1.RoleLister) + RegisterRoleBindingLister(namespace string, lister rbacv1.RoleBindingLister) + + ClusterRoleLister() rbacv1.ClusterRoleLister + ClusterRoleBindingLister() rbacv1.ClusterRoleBindingLister + RoleLister() rbacv1.RoleLister + RoleBindingLister() rbacv1.RoleBindingLister +} + +//go:generate counterfeiter . APIRegistrationV1Lister +type APIRegistrationV1Lister interface { + RegisterAPIServiceLister(lister aregv1.APIServiceLister) + + APIServiceLister() aregv1.APIServiceLister +} + +//go:generate counterfeiter . APIExtensionsV1beta1Lister +type APIExtensionsV1beta1Lister interface { + RegisterCustomResourceDefinitionLister(lister aextv1beta1.CustomResourceDefinitionLister) + + CustomResourceDefinitionLister() aextv1beta1.CustomResourceDefinitionLister +} + +//go:generate counterfeiter . OperatorsV1alpha1Lister +type OperatorsV1alpha1Lister interface { + RegisterClusterServiceVersionLister(namespace string, lister v1alpha1.ClusterServiceVersionLister) + RegisterSubscriptionLister(namespace string, lister v1alpha1.SubscriptionLister) + RegisterInstallPlanLister(namespace string, lister v1alpha1.InstallPlanLister) + + ClusterServiceVersionLister() v1alpha1.ClusterServiceVersionLister + SubscriptionLister() v1alpha1.SubscriptionLister + InstallPlanLister() v1alpha1.InstallPlanLister +} + +//go:generate counterfeiter . OperatorsV1Lister +type OperatorsV1Lister interface { + RegisterOperatorGroupLister(namespace string, lister v1.OperatorGroupLister) + + OperatorGroupLister() v1.OperatorGroupLister +} + +type appsV1Lister struct { + deploymentLister *UnionDeploymentLister +} + +func newAppsV1Lister() *appsV1Lister { + return &appsV1Lister{ + deploymentLister: &UnionDeploymentLister{}, + } +} + +type coreV1Lister struct { + secretLister *UnionSecretLister + serviceLister *UnionServiceLister + serviceAccountLister *UnionServiceAccountLister + namespaceLister *UnionNamespaceLister + podLister *UnionPodLister + configMapLister *UnionConfigMapLister +} + +func newCoreV1Lister() *coreV1Lister { + return &coreV1Lister{ + secretLister: &UnionSecretLister{}, + serviceLister: &UnionServiceLister{}, + serviceAccountLister: &UnionServiceAccountLister{}, + namespaceLister: &UnionNamespaceLister{}, + podLister: &UnionPodLister{}, + configMapLister: &UnionConfigMapLister{}, + } +} + +type rbacV1Lister struct { + roleLister *UnionRoleLister + roleBindingLister *UnionRoleBindingLister + clusterRoleLister *UnionClusterRoleLister + clusterRoleBindingLister *UnionClusterRoleBindingLister +} + +func newRbacV1Lister() *rbacV1Lister { + return &rbacV1Lister{ + roleLister: &UnionRoleLister{}, + roleBindingLister: &UnionRoleBindingLister{}, + clusterRoleLister: &UnionClusterRoleLister{}, + clusterRoleBindingLister: &UnionClusterRoleBindingLister{}, + } +} + +type apiRegistrationV1Lister struct { + apiServiceLister *UnionAPIServiceLister +} + +func newAPIRegistrationV1Lister() *apiRegistrationV1Lister { + return &apiRegistrationV1Lister{ + apiServiceLister: &UnionAPIServiceLister{}, + } +} + +type apiExtensionsV1beta1Lister struct { + customResourceDefinitionLister *UnionCustomResourceDefinitionLister +} + +func newAPIExtensionsV1beta1Lister() *apiExtensionsV1beta1Lister { + return &apiExtensionsV1beta1Lister{ + customResourceDefinitionLister: &UnionCustomResourceDefinitionLister{}, + } +} + +type operatorsV1alpha1Lister struct { + clusterServiceVersionLister *UnionClusterServiceVersionLister + subscriptionLister *UnionSubscriptionLister + installPlanLister *UnionInstallPlanLister +} + +func newOperatorsV1alpha1Lister() *operatorsV1alpha1Lister { + return &operatorsV1alpha1Lister{ + clusterServiceVersionLister: &UnionClusterServiceVersionLister{}, + subscriptionLister: &UnionSubscriptionLister{}, + installPlanLister: &UnionInstallPlanLister{}, + } +} + +type operatorsV1Lister struct { + operatorGroupLister *UnionOperatorGroupLister +} + +func newOperatorsV1Lister() *operatorsV1Lister { + return &operatorsV1Lister{ + operatorGroupLister: &UnionOperatorGroupLister{}, + } +} + +// Interface assertion +var _ OperatorLister = &lister{} + +type lister struct { + appsV1Lister *appsV1Lister + coreV1Lister *coreV1Lister + rbacV1Lister *rbacV1Lister + apiRegistrationV1Lister *apiRegistrationV1Lister + apiExtensionsV1beta1Lister *apiExtensionsV1beta1Lister + + operatorsV1alpha1Lister *operatorsV1alpha1Lister + operatorsV1Lister *operatorsV1Lister +} + +func (l *lister) AppsV1() AppsV1Lister { + return l.appsV1Lister +} + +func (l *lister) CoreV1() CoreV1Lister { + return l.coreV1Lister +} + +func (l *lister) RbacV1() RbacV1Lister { + return l.rbacV1Lister +} + +func (l *lister) APIRegistrationV1() APIRegistrationV1Lister { + return l.apiRegistrationV1Lister +} + +func (l *lister) APIExtensionsV1beta1() APIExtensionsV1beta1Lister { + return l.apiExtensionsV1beta1Lister +} + +func (l *lister) OperatorsV1alpha1() OperatorsV1alpha1Lister { + return l.operatorsV1alpha1Lister +} + +func (l *lister) OperatorsV1() OperatorsV1Lister { + return l.operatorsV1Lister +} + +func NewLister() OperatorLister { + // TODO: better initialization + return &lister{ + appsV1Lister: newAppsV1Lister(), + coreV1Lister: newCoreV1Lister(), + rbacV1Lister: newRbacV1Lister(), + apiRegistrationV1Lister: newAPIRegistrationV1Lister(), + apiExtensionsV1beta1Lister: newAPIExtensionsV1beta1Lister(), + + operatorsV1alpha1Lister: newOperatorsV1alpha1Lister(), + operatorsV1Lister: newOperatorsV1Lister(), + } +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/namespace.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/namespace.go new file mode 100644 index 0000000000..1aaf302eb9 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/namespace.go @@ -0,0 +1,51 @@ +package operatorlister + +import ( + "fmt" + "sync" + + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/labels" + corev1 "k8s.io/client-go/listers/core/v1" +) + +type UnionNamespaceLister struct { + namespaceLister corev1.NamespaceLister + namespaceLock sync.RWMutex +} + +// List lists all Namespaces in the indexer. +func (unl *UnionNamespaceLister) List(selector labels.Selector) (ret []*v1.Namespace, err error) { + unl.namespaceLock.RLock() + defer unl.namespaceLock.RUnlock() + + if unl.namespaceLister == nil { + return nil, fmt.Errorf("no namespace lister registered") + } + return unl.namespaceLister.List(selector) +} + +func (unl *UnionNamespaceLister) Get(name string) (*v1.Namespace, error) { + unl.namespaceLock.RLock() + defer unl.namespaceLock.RUnlock() + + if unl.namespaceLister == nil { + return nil, fmt.Errorf("no namespace lister registered") + } + return unl.namespaceLister.Get(name) +} + +func (unl *UnionNamespaceLister) RegisterNamespaceLister(lister corev1.NamespaceLister) { + unl.namespaceLock.Lock() + defer unl.namespaceLock.Unlock() + + unl.namespaceLister = lister +} + +func (l *coreV1Lister) RegisterNamespaceLister(lister corev1.NamespaceLister) { + l.namespaceLister.RegisterNamespaceLister(lister) +} + +func (l *coreV1Lister) NamespaceLister() corev1.NamespaceLister { + return l.namespaceLister +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/operatorgroup.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/operatorgroup.go new file mode 100644 index 0000000000..75111f69da --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/operatorgroup.go @@ -0,0 +1,96 @@ +package operatorlister + +import ( + "fmt" + "sync" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/types" + + "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1" + listers "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1" +) + +type UnionOperatorGroupLister struct { + csvListers map[string]listers.OperatorGroupLister + csvLock sync.RWMutex +} + +// List lists all OperatorGroups in the indexer. +func (uol *UnionOperatorGroupLister) List(selector labels.Selector) (ret []*v1.OperatorGroup, err error) { + uol.csvLock.RLock() + defer uol.csvLock.RUnlock() + + set := make(map[types.UID]*v1.OperatorGroup) + for _, cl := range uol.csvListers { + csvs, err := cl.List(selector) + if err != nil { + return nil, err + } + + for _, csv := range csvs { + set[csv.GetUID()] = csv + } + } + + for _, csv := range set { + ret = append(ret, csv) + } + + return +} + +// OperatorGroups returns an object that can list and get OperatorGroups. +func (uol *UnionOperatorGroupLister) OperatorGroups(namespace string) listers.OperatorGroupNamespaceLister { + uol.csvLock.RLock() + defer uol.csvLock.RUnlock() + + // Check for specific namespace listers + if cl, ok := uol.csvListers[namespace]; ok { + return cl.OperatorGroups(namespace) + } + + // Check for any namespace-all listers + if cl, ok := uol.csvListers[metav1.NamespaceAll]; ok { + return cl.OperatorGroups(namespace) + } + + return &NullOperatorGroupNamespaceLister{} +} + +func (uol *UnionOperatorGroupLister) RegisterOperatorGroupLister(namespace string, lister listers.OperatorGroupLister) { + uol.csvLock.Lock() + defer uol.csvLock.Unlock() + + if uol.csvListers == nil { + uol.csvListers = make(map[string]listers.OperatorGroupLister) + } + + uol.csvListers[namespace] = lister +} + +func (l *operatorsV1Lister) RegisterOperatorGroupLister(namespace string, lister listers.OperatorGroupLister) { + l.operatorGroupLister.RegisterOperatorGroupLister(namespace, lister) +} + +func (l *operatorsV1Lister) OperatorGroupLister() listers.OperatorGroupLister { + return l.operatorGroupLister +} + +// NullOperatorGroupNamespaceLister is an implementation of a null OperatorGroupNamespaceLister. It is +// used to prevent nil pointers when no OperatorGroupNamespaceLister has been registered for a given +// namespace. +type NullOperatorGroupNamespaceLister struct { + listers.OperatorGroupNamespaceLister +} + +// List returns nil and an error explaining that this is a NullOperatorGroupNamespaceLister. +func (n *NullOperatorGroupNamespaceLister) List(selector labels.Selector) (ret []*v1.OperatorGroup, err error) { + return nil, fmt.Errorf("cannot list OperatorGroups with a NullOperatorGroupNamespaceLister") +} + +// Get returns nil and an error explaining that this is a NullOperatorGroupNamespaceLister. +func (n *NullOperatorGroupNamespaceLister) Get(name string) (*v1.OperatorGroup, error) { + return nil, fmt.Errorf("cannot get OperatorGroup with a NullOperatorGroupNamespaceLister") +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/operatorlisterfakes/fake_apiextensions_v1beta1lister.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/operatorlisterfakes/fake_apiextensions_v1beta1lister.go new file mode 100644 index 0000000000..536cd24715 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/operatorlisterfakes/fake_apiextensions_v1beta1lister.go @@ -0,0 +1,140 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package operatorlisterfakes + +import ( + sync "sync" + + operatorlister "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister" + v1beta1 "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1beta1" +) + +type FakeAPIExtensionsV1beta1Lister struct { + CustomResourceDefinitionListerStub func() v1beta1.CustomResourceDefinitionLister + customResourceDefinitionListerMutex sync.RWMutex + customResourceDefinitionListerArgsForCall []struct { + } + customResourceDefinitionListerReturns struct { + result1 v1beta1.CustomResourceDefinitionLister + } + customResourceDefinitionListerReturnsOnCall map[int]struct { + result1 v1beta1.CustomResourceDefinitionLister + } + RegisterCustomResourceDefinitionListerStub func(v1beta1.CustomResourceDefinitionLister) + registerCustomResourceDefinitionListerMutex sync.RWMutex + registerCustomResourceDefinitionListerArgsForCall []struct { + arg1 v1beta1.CustomResourceDefinitionLister + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *FakeAPIExtensionsV1beta1Lister) CustomResourceDefinitionLister() v1beta1.CustomResourceDefinitionLister { + fake.customResourceDefinitionListerMutex.Lock() + ret, specificReturn := fake.customResourceDefinitionListerReturnsOnCall[len(fake.customResourceDefinitionListerArgsForCall)] + fake.customResourceDefinitionListerArgsForCall = append(fake.customResourceDefinitionListerArgsForCall, struct { + }{}) + fake.recordInvocation("CustomResourceDefinitionLister", []interface{}{}) + fake.customResourceDefinitionListerMutex.Unlock() + if fake.CustomResourceDefinitionListerStub != nil { + return fake.CustomResourceDefinitionListerStub() + } + if specificReturn { + return ret.result1 + } + fakeReturns := fake.customResourceDefinitionListerReturns + return fakeReturns.result1 +} + +func (fake *FakeAPIExtensionsV1beta1Lister) CustomResourceDefinitionListerCallCount() int { + fake.customResourceDefinitionListerMutex.RLock() + defer fake.customResourceDefinitionListerMutex.RUnlock() + return len(fake.customResourceDefinitionListerArgsForCall) +} + +func (fake *FakeAPIExtensionsV1beta1Lister) CustomResourceDefinitionListerCalls(stub func() v1beta1.CustomResourceDefinitionLister) { + fake.customResourceDefinitionListerMutex.Lock() + defer fake.customResourceDefinitionListerMutex.Unlock() + fake.CustomResourceDefinitionListerStub = stub +} + +func (fake *FakeAPIExtensionsV1beta1Lister) CustomResourceDefinitionListerReturns(result1 v1beta1.CustomResourceDefinitionLister) { + fake.customResourceDefinitionListerMutex.Lock() + defer fake.customResourceDefinitionListerMutex.Unlock() + fake.CustomResourceDefinitionListerStub = nil + fake.customResourceDefinitionListerReturns = struct { + result1 v1beta1.CustomResourceDefinitionLister + }{result1} +} + +func (fake *FakeAPIExtensionsV1beta1Lister) CustomResourceDefinitionListerReturnsOnCall(i int, result1 v1beta1.CustomResourceDefinitionLister) { + fake.customResourceDefinitionListerMutex.Lock() + defer fake.customResourceDefinitionListerMutex.Unlock() + fake.CustomResourceDefinitionListerStub = nil + if fake.customResourceDefinitionListerReturnsOnCall == nil { + fake.customResourceDefinitionListerReturnsOnCall = make(map[int]struct { + result1 v1beta1.CustomResourceDefinitionLister + }) + } + fake.customResourceDefinitionListerReturnsOnCall[i] = struct { + result1 v1beta1.CustomResourceDefinitionLister + }{result1} +} + +func (fake *FakeAPIExtensionsV1beta1Lister) RegisterCustomResourceDefinitionLister(arg1 v1beta1.CustomResourceDefinitionLister) { + fake.registerCustomResourceDefinitionListerMutex.Lock() + fake.registerCustomResourceDefinitionListerArgsForCall = append(fake.registerCustomResourceDefinitionListerArgsForCall, struct { + arg1 v1beta1.CustomResourceDefinitionLister + }{arg1}) + fake.recordInvocation("RegisterCustomResourceDefinitionLister", []interface{}{arg1}) + fake.registerCustomResourceDefinitionListerMutex.Unlock() + if fake.RegisterCustomResourceDefinitionListerStub != nil { + fake.RegisterCustomResourceDefinitionListerStub(arg1) + } +} + +func (fake *FakeAPIExtensionsV1beta1Lister) RegisterCustomResourceDefinitionListerCallCount() int { + fake.registerCustomResourceDefinitionListerMutex.RLock() + defer fake.registerCustomResourceDefinitionListerMutex.RUnlock() + return len(fake.registerCustomResourceDefinitionListerArgsForCall) +} + +func (fake *FakeAPIExtensionsV1beta1Lister) RegisterCustomResourceDefinitionListerCalls(stub func(v1beta1.CustomResourceDefinitionLister)) { + fake.registerCustomResourceDefinitionListerMutex.Lock() + defer fake.registerCustomResourceDefinitionListerMutex.Unlock() + fake.RegisterCustomResourceDefinitionListerStub = stub +} + +func (fake *FakeAPIExtensionsV1beta1Lister) RegisterCustomResourceDefinitionListerArgsForCall(i int) v1beta1.CustomResourceDefinitionLister { + fake.registerCustomResourceDefinitionListerMutex.RLock() + defer fake.registerCustomResourceDefinitionListerMutex.RUnlock() + argsForCall := fake.registerCustomResourceDefinitionListerArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FakeAPIExtensionsV1beta1Lister) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.customResourceDefinitionListerMutex.RLock() + defer fake.customResourceDefinitionListerMutex.RUnlock() + fake.registerCustomResourceDefinitionListerMutex.RLock() + defer fake.registerCustomResourceDefinitionListerMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *FakeAPIExtensionsV1beta1Lister) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} + +var _ operatorlister.APIExtensionsV1beta1Lister = new(FakeAPIExtensionsV1beta1Lister) diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/operatorlisterfakes/fake_apiregistration_v1lister.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/operatorlisterfakes/fake_apiregistration_v1lister.go new file mode 100644 index 0000000000..a27e12b40f --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/operatorlisterfakes/fake_apiregistration_v1lister.go @@ -0,0 +1,140 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package operatorlisterfakes + +import ( + sync "sync" + + operatorlister "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister" + v1 "k8s.io/kube-aggregator/pkg/client/listers/apiregistration/v1" +) + +type FakeAPIRegistrationV1Lister struct { + APIServiceListerStub func() v1.APIServiceLister + aPIServiceListerMutex sync.RWMutex + aPIServiceListerArgsForCall []struct { + } + aPIServiceListerReturns struct { + result1 v1.APIServiceLister + } + aPIServiceListerReturnsOnCall map[int]struct { + result1 v1.APIServiceLister + } + RegisterAPIServiceListerStub func(v1.APIServiceLister) + registerAPIServiceListerMutex sync.RWMutex + registerAPIServiceListerArgsForCall []struct { + arg1 v1.APIServiceLister + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *FakeAPIRegistrationV1Lister) APIServiceLister() v1.APIServiceLister { + fake.aPIServiceListerMutex.Lock() + ret, specificReturn := fake.aPIServiceListerReturnsOnCall[len(fake.aPIServiceListerArgsForCall)] + fake.aPIServiceListerArgsForCall = append(fake.aPIServiceListerArgsForCall, struct { + }{}) + fake.recordInvocation("APIServiceLister", []interface{}{}) + fake.aPIServiceListerMutex.Unlock() + if fake.APIServiceListerStub != nil { + return fake.APIServiceListerStub() + } + if specificReturn { + return ret.result1 + } + fakeReturns := fake.aPIServiceListerReturns + return fakeReturns.result1 +} + +func (fake *FakeAPIRegistrationV1Lister) APIServiceListerCallCount() int { + fake.aPIServiceListerMutex.RLock() + defer fake.aPIServiceListerMutex.RUnlock() + return len(fake.aPIServiceListerArgsForCall) +} + +func (fake *FakeAPIRegistrationV1Lister) APIServiceListerCalls(stub func() v1.APIServiceLister) { + fake.aPIServiceListerMutex.Lock() + defer fake.aPIServiceListerMutex.Unlock() + fake.APIServiceListerStub = stub +} + +func (fake *FakeAPIRegistrationV1Lister) APIServiceListerReturns(result1 v1.APIServiceLister) { + fake.aPIServiceListerMutex.Lock() + defer fake.aPIServiceListerMutex.Unlock() + fake.APIServiceListerStub = nil + fake.aPIServiceListerReturns = struct { + result1 v1.APIServiceLister + }{result1} +} + +func (fake *FakeAPIRegistrationV1Lister) APIServiceListerReturnsOnCall(i int, result1 v1.APIServiceLister) { + fake.aPIServiceListerMutex.Lock() + defer fake.aPIServiceListerMutex.Unlock() + fake.APIServiceListerStub = nil + if fake.aPIServiceListerReturnsOnCall == nil { + fake.aPIServiceListerReturnsOnCall = make(map[int]struct { + result1 v1.APIServiceLister + }) + } + fake.aPIServiceListerReturnsOnCall[i] = struct { + result1 v1.APIServiceLister + }{result1} +} + +func (fake *FakeAPIRegistrationV1Lister) RegisterAPIServiceLister(arg1 v1.APIServiceLister) { + fake.registerAPIServiceListerMutex.Lock() + fake.registerAPIServiceListerArgsForCall = append(fake.registerAPIServiceListerArgsForCall, struct { + arg1 v1.APIServiceLister + }{arg1}) + fake.recordInvocation("RegisterAPIServiceLister", []interface{}{arg1}) + fake.registerAPIServiceListerMutex.Unlock() + if fake.RegisterAPIServiceListerStub != nil { + fake.RegisterAPIServiceListerStub(arg1) + } +} + +func (fake *FakeAPIRegistrationV1Lister) RegisterAPIServiceListerCallCount() int { + fake.registerAPIServiceListerMutex.RLock() + defer fake.registerAPIServiceListerMutex.RUnlock() + return len(fake.registerAPIServiceListerArgsForCall) +} + +func (fake *FakeAPIRegistrationV1Lister) RegisterAPIServiceListerCalls(stub func(v1.APIServiceLister)) { + fake.registerAPIServiceListerMutex.Lock() + defer fake.registerAPIServiceListerMutex.Unlock() + fake.RegisterAPIServiceListerStub = stub +} + +func (fake *FakeAPIRegistrationV1Lister) RegisterAPIServiceListerArgsForCall(i int) v1.APIServiceLister { + fake.registerAPIServiceListerMutex.RLock() + defer fake.registerAPIServiceListerMutex.RUnlock() + argsForCall := fake.registerAPIServiceListerArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FakeAPIRegistrationV1Lister) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.aPIServiceListerMutex.RLock() + defer fake.aPIServiceListerMutex.RUnlock() + fake.registerAPIServiceListerMutex.RLock() + defer fake.registerAPIServiceListerMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *FakeAPIRegistrationV1Lister) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} + +var _ operatorlister.APIRegistrationV1Lister = new(FakeAPIRegistrationV1Lister) diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/operatorlisterfakes/fake_apps_v1lister.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/operatorlisterfakes/fake_apps_v1lister.go new file mode 100644 index 0000000000..eb4224e2c7 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/operatorlisterfakes/fake_apps_v1lister.go @@ -0,0 +1,142 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package operatorlisterfakes + +import ( + sync "sync" + + operatorlister "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister" + v1 "k8s.io/client-go/listers/apps/v1" +) + +type FakeAppsV1Lister struct { + DeploymentListerStub func() v1.DeploymentLister + deploymentListerMutex sync.RWMutex + deploymentListerArgsForCall []struct { + } + deploymentListerReturns struct { + result1 v1.DeploymentLister + } + deploymentListerReturnsOnCall map[int]struct { + result1 v1.DeploymentLister + } + RegisterDeploymentListerStub func(string, v1.DeploymentLister) + registerDeploymentListerMutex sync.RWMutex + registerDeploymentListerArgsForCall []struct { + arg1 string + arg2 v1.DeploymentLister + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *FakeAppsV1Lister) DeploymentLister() v1.DeploymentLister { + fake.deploymentListerMutex.Lock() + ret, specificReturn := fake.deploymentListerReturnsOnCall[len(fake.deploymentListerArgsForCall)] + fake.deploymentListerArgsForCall = append(fake.deploymentListerArgsForCall, struct { + }{}) + fake.recordInvocation("DeploymentLister", []interface{}{}) + fake.deploymentListerMutex.Unlock() + if fake.DeploymentListerStub != nil { + return fake.DeploymentListerStub() + } + if specificReturn { + return ret.result1 + } + fakeReturns := fake.deploymentListerReturns + return fakeReturns.result1 +} + +func (fake *FakeAppsV1Lister) DeploymentListerCallCount() int { + fake.deploymentListerMutex.RLock() + defer fake.deploymentListerMutex.RUnlock() + return len(fake.deploymentListerArgsForCall) +} + +func (fake *FakeAppsV1Lister) DeploymentListerCalls(stub func() v1.DeploymentLister) { + fake.deploymentListerMutex.Lock() + defer fake.deploymentListerMutex.Unlock() + fake.DeploymentListerStub = stub +} + +func (fake *FakeAppsV1Lister) DeploymentListerReturns(result1 v1.DeploymentLister) { + fake.deploymentListerMutex.Lock() + defer fake.deploymentListerMutex.Unlock() + fake.DeploymentListerStub = nil + fake.deploymentListerReturns = struct { + result1 v1.DeploymentLister + }{result1} +} + +func (fake *FakeAppsV1Lister) DeploymentListerReturnsOnCall(i int, result1 v1.DeploymentLister) { + fake.deploymentListerMutex.Lock() + defer fake.deploymentListerMutex.Unlock() + fake.DeploymentListerStub = nil + if fake.deploymentListerReturnsOnCall == nil { + fake.deploymentListerReturnsOnCall = make(map[int]struct { + result1 v1.DeploymentLister + }) + } + fake.deploymentListerReturnsOnCall[i] = struct { + result1 v1.DeploymentLister + }{result1} +} + +func (fake *FakeAppsV1Lister) RegisterDeploymentLister(arg1 string, arg2 v1.DeploymentLister) { + fake.registerDeploymentListerMutex.Lock() + fake.registerDeploymentListerArgsForCall = append(fake.registerDeploymentListerArgsForCall, struct { + arg1 string + arg2 v1.DeploymentLister + }{arg1, arg2}) + fake.recordInvocation("RegisterDeploymentLister", []interface{}{arg1, arg2}) + fake.registerDeploymentListerMutex.Unlock() + if fake.RegisterDeploymentListerStub != nil { + fake.RegisterDeploymentListerStub(arg1, arg2) + } +} + +func (fake *FakeAppsV1Lister) RegisterDeploymentListerCallCount() int { + fake.registerDeploymentListerMutex.RLock() + defer fake.registerDeploymentListerMutex.RUnlock() + return len(fake.registerDeploymentListerArgsForCall) +} + +func (fake *FakeAppsV1Lister) RegisterDeploymentListerCalls(stub func(string, v1.DeploymentLister)) { + fake.registerDeploymentListerMutex.Lock() + defer fake.registerDeploymentListerMutex.Unlock() + fake.RegisterDeploymentListerStub = stub +} + +func (fake *FakeAppsV1Lister) RegisterDeploymentListerArgsForCall(i int) (string, v1.DeploymentLister) { + fake.registerDeploymentListerMutex.RLock() + defer fake.registerDeploymentListerMutex.RUnlock() + argsForCall := fake.registerDeploymentListerArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2 +} + +func (fake *FakeAppsV1Lister) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.deploymentListerMutex.RLock() + defer fake.deploymentListerMutex.RUnlock() + fake.registerDeploymentListerMutex.RLock() + defer fake.registerDeploymentListerMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *FakeAppsV1Lister) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} + +var _ operatorlister.AppsV1Lister = new(FakeAppsV1Lister) diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/operatorlisterfakes/fake_core_v1lister.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/operatorlisterfakes/fake_core_v1lister.go new file mode 100644 index 0000000000..5c3505da57 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/operatorlisterfakes/fake_core_v1lister.go @@ -0,0 +1,660 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package operatorlisterfakes + +import ( + sync "sync" + + operatorlister "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister" + v1 "k8s.io/client-go/listers/core/v1" +) + +type FakeCoreV1Lister struct { + ConfigMapListerStub func() v1.ConfigMapLister + configMapListerMutex sync.RWMutex + configMapListerArgsForCall []struct { + } + configMapListerReturns struct { + result1 v1.ConfigMapLister + } + configMapListerReturnsOnCall map[int]struct { + result1 v1.ConfigMapLister + } + NamespaceListerStub func() v1.NamespaceLister + namespaceListerMutex sync.RWMutex + namespaceListerArgsForCall []struct { + } + namespaceListerReturns struct { + result1 v1.NamespaceLister + } + namespaceListerReturnsOnCall map[int]struct { + result1 v1.NamespaceLister + } + PodListerStub func() v1.PodLister + podListerMutex sync.RWMutex + podListerArgsForCall []struct { + } + podListerReturns struct { + result1 v1.PodLister + } + podListerReturnsOnCall map[int]struct { + result1 v1.PodLister + } + RegisterConfigMapListerStub func(string, v1.ConfigMapLister) + registerConfigMapListerMutex sync.RWMutex + registerConfigMapListerArgsForCall []struct { + arg1 string + arg2 v1.ConfigMapLister + } + RegisterNamespaceListerStub func(v1.NamespaceLister) + registerNamespaceListerMutex sync.RWMutex + registerNamespaceListerArgsForCall []struct { + arg1 v1.NamespaceLister + } + RegisterPodListerStub func(string, v1.PodLister) + registerPodListerMutex sync.RWMutex + registerPodListerArgsForCall []struct { + arg1 string + arg2 v1.PodLister + } + RegisterSecretListerStub func(string, v1.SecretLister) + registerSecretListerMutex sync.RWMutex + registerSecretListerArgsForCall []struct { + arg1 string + arg2 v1.SecretLister + } + RegisterServiceAccountListerStub func(string, v1.ServiceAccountLister) + registerServiceAccountListerMutex sync.RWMutex + registerServiceAccountListerArgsForCall []struct { + arg1 string + arg2 v1.ServiceAccountLister + } + RegisterServiceListerStub func(string, v1.ServiceLister) + registerServiceListerMutex sync.RWMutex + registerServiceListerArgsForCall []struct { + arg1 string + arg2 v1.ServiceLister + } + SecretListerStub func() v1.SecretLister + secretListerMutex sync.RWMutex + secretListerArgsForCall []struct { + } + secretListerReturns struct { + result1 v1.SecretLister + } + secretListerReturnsOnCall map[int]struct { + result1 v1.SecretLister + } + ServiceAccountListerStub func() v1.ServiceAccountLister + serviceAccountListerMutex sync.RWMutex + serviceAccountListerArgsForCall []struct { + } + serviceAccountListerReturns struct { + result1 v1.ServiceAccountLister + } + serviceAccountListerReturnsOnCall map[int]struct { + result1 v1.ServiceAccountLister + } + ServiceListerStub func() v1.ServiceLister + serviceListerMutex sync.RWMutex + serviceListerArgsForCall []struct { + } + serviceListerReturns struct { + result1 v1.ServiceLister + } + serviceListerReturnsOnCall map[int]struct { + result1 v1.ServiceLister + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *FakeCoreV1Lister) ConfigMapLister() v1.ConfigMapLister { + fake.configMapListerMutex.Lock() + ret, specificReturn := fake.configMapListerReturnsOnCall[len(fake.configMapListerArgsForCall)] + fake.configMapListerArgsForCall = append(fake.configMapListerArgsForCall, struct { + }{}) + fake.recordInvocation("ConfigMapLister", []interface{}{}) + fake.configMapListerMutex.Unlock() + if fake.ConfigMapListerStub != nil { + return fake.ConfigMapListerStub() + } + if specificReturn { + return ret.result1 + } + fakeReturns := fake.configMapListerReturns + return fakeReturns.result1 +} + +func (fake *FakeCoreV1Lister) ConfigMapListerCallCount() int { + fake.configMapListerMutex.RLock() + defer fake.configMapListerMutex.RUnlock() + return len(fake.configMapListerArgsForCall) +} + +func (fake *FakeCoreV1Lister) ConfigMapListerCalls(stub func() v1.ConfigMapLister) { + fake.configMapListerMutex.Lock() + defer fake.configMapListerMutex.Unlock() + fake.ConfigMapListerStub = stub +} + +func (fake *FakeCoreV1Lister) ConfigMapListerReturns(result1 v1.ConfigMapLister) { + fake.configMapListerMutex.Lock() + defer fake.configMapListerMutex.Unlock() + fake.ConfigMapListerStub = nil + fake.configMapListerReturns = struct { + result1 v1.ConfigMapLister + }{result1} +} + +func (fake *FakeCoreV1Lister) ConfigMapListerReturnsOnCall(i int, result1 v1.ConfigMapLister) { + fake.configMapListerMutex.Lock() + defer fake.configMapListerMutex.Unlock() + fake.ConfigMapListerStub = nil + if fake.configMapListerReturnsOnCall == nil { + fake.configMapListerReturnsOnCall = make(map[int]struct { + result1 v1.ConfigMapLister + }) + } + fake.configMapListerReturnsOnCall[i] = struct { + result1 v1.ConfigMapLister + }{result1} +} + +func (fake *FakeCoreV1Lister) NamespaceLister() v1.NamespaceLister { + fake.namespaceListerMutex.Lock() + ret, specificReturn := fake.namespaceListerReturnsOnCall[len(fake.namespaceListerArgsForCall)] + fake.namespaceListerArgsForCall = append(fake.namespaceListerArgsForCall, struct { + }{}) + fake.recordInvocation("NamespaceLister", []interface{}{}) + fake.namespaceListerMutex.Unlock() + if fake.NamespaceListerStub != nil { + return fake.NamespaceListerStub() + } + if specificReturn { + return ret.result1 + } + fakeReturns := fake.namespaceListerReturns + return fakeReturns.result1 +} + +func (fake *FakeCoreV1Lister) NamespaceListerCallCount() int { + fake.namespaceListerMutex.RLock() + defer fake.namespaceListerMutex.RUnlock() + return len(fake.namespaceListerArgsForCall) +} + +func (fake *FakeCoreV1Lister) NamespaceListerCalls(stub func() v1.NamespaceLister) { + fake.namespaceListerMutex.Lock() + defer fake.namespaceListerMutex.Unlock() + fake.NamespaceListerStub = stub +} + +func (fake *FakeCoreV1Lister) NamespaceListerReturns(result1 v1.NamespaceLister) { + fake.namespaceListerMutex.Lock() + defer fake.namespaceListerMutex.Unlock() + fake.NamespaceListerStub = nil + fake.namespaceListerReturns = struct { + result1 v1.NamespaceLister + }{result1} +} + +func (fake *FakeCoreV1Lister) NamespaceListerReturnsOnCall(i int, result1 v1.NamespaceLister) { + fake.namespaceListerMutex.Lock() + defer fake.namespaceListerMutex.Unlock() + fake.NamespaceListerStub = nil + if fake.namespaceListerReturnsOnCall == nil { + fake.namespaceListerReturnsOnCall = make(map[int]struct { + result1 v1.NamespaceLister + }) + } + fake.namespaceListerReturnsOnCall[i] = struct { + result1 v1.NamespaceLister + }{result1} +} + +func (fake *FakeCoreV1Lister) PodLister() v1.PodLister { + fake.podListerMutex.Lock() + ret, specificReturn := fake.podListerReturnsOnCall[len(fake.podListerArgsForCall)] + fake.podListerArgsForCall = append(fake.podListerArgsForCall, struct { + }{}) + fake.recordInvocation("PodLister", []interface{}{}) + fake.podListerMutex.Unlock() + if fake.PodListerStub != nil { + return fake.PodListerStub() + } + if specificReturn { + return ret.result1 + } + fakeReturns := fake.podListerReturns + return fakeReturns.result1 +} + +func (fake *FakeCoreV1Lister) PodListerCallCount() int { + fake.podListerMutex.RLock() + defer fake.podListerMutex.RUnlock() + return len(fake.podListerArgsForCall) +} + +func (fake *FakeCoreV1Lister) PodListerCalls(stub func() v1.PodLister) { + fake.podListerMutex.Lock() + defer fake.podListerMutex.Unlock() + fake.PodListerStub = stub +} + +func (fake *FakeCoreV1Lister) PodListerReturns(result1 v1.PodLister) { + fake.podListerMutex.Lock() + defer fake.podListerMutex.Unlock() + fake.PodListerStub = nil + fake.podListerReturns = struct { + result1 v1.PodLister + }{result1} +} + +func (fake *FakeCoreV1Lister) PodListerReturnsOnCall(i int, result1 v1.PodLister) { + fake.podListerMutex.Lock() + defer fake.podListerMutex.Unlock() + fake.PodListerStub = nil + if fake.podListerReturnsOnCall == nil { + fake.podListerReturnsOnCall = make(map[int]struct { + result1 v1.PodLister + }) + } + fake.podListerReturnsOnCall[i] = struct { + result1 v1.PodLister + }{result1} +} + +func (fake *FakeCoreV1Lister) RegisterConfigMapLister(arg1 string, arg2 v1.ConfigMapLister) { + fake.registerConfigMapListerMutex.Lock() + fake.registerConfigMapListerArgsForCall = append(fake.registerConfigMapListerArgsForCall, struct { + arg1 string + arg2 v1.ConfigMapLister + }{arg1, arg2}) + fake.recordInvocation("RegisterConfigMapLister", []interface{}{arg1, arg2}) + fake.registerConfigMapListerMutex.Unlock() + if fake.RegisterConfigMapListerStub != nil { + fake.RegisterConfigMapListerStub(arg1, arg2) + } +} + +func (fake *FakeCoreV1Lister) RegisterConfigMapListerCallCount() int { + fake.registerConfigMapListerMutex.RLock() + defer fake.registerConfigMapListerMutex.RUnlock() + return len(fake.registerConfigMapListerArgsForCall) +} + +func (fake *FakeCoreV1Lister) RegisterConfigMapListerCalls(stub func(string, v1.ConfigMapLister)) { + fake.registerConfigMapListerMutex.Lock() + defer fake.registerConfigMapListerMutex.Unlock() + fake.RegisterConfigMapListerStub = stub +} + +func (fake *FakeCoreV1Lister) RegisterConfigMapListerArgsForCall(i int) (string, v1.ConfigMapLister) { + fake.registerConfigMapListerMutex.RLock() + defer fake.registerConfigMapListerMutex.RUnlock() + argsForCall := fake.registerConfigMapListerArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2 +} + +func (fake *FakeCoreV1Lister) RegisterNamespaceLister(arg1 v1.NamespaceLister) { + fake.registerNamespaceListerMutex.Lock() + fake.registerNamespaceListerArgsForCall = append(fake.registerNamespaceListerArgsForCall, struct { + arg1 v1.NamespaceLister + }{arg1}) + fake.recordInvocation("RegisterNamespaceLister", []interface{}{arg1}) + fake.registerNamespaceListerMutex.Unlock() + if fake.RegisterNamespaceListerStub != nil { + fake.RegisterNamespaceListerStub(arg1) + } +} + +func (fake *FakeCoreV1Lister) RegisterNamespaceListerCallCount() int { + fake.registerNamespaceListerMutex.RLock() + defer fake.registerNamespaceListerMutex.RUnlock() + return len(fake.registerNamespaceListerArgsForCall) +} + +func (fake *FakeCoreV1Lister) RegisterNamespaceListerCalls(stub func(v1.NamespaceLister)) { + fake.registerNamespaceListerMutex.Lock() + defer fake.registerNamespaceListerMutex.Unlock() + fake.RegisterNamespaceListerStub = stub +} + +func (fake *FakeCoreV1Lister) RegisterNamespaceListerArgsForCall(i int) v1.NamespaceLister { + fake.registerNamespaceListerMutex.RLock() + defer fake.registerNamespaceListerMutex.RUnlock() + argsForCall := fake.registerNamespaceListerArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FakeCoreV1Lister) RegisterPodLister(arg1 string, arg2 v1.PodLister) { + fake.registerPodListerMutex.Lock() + fake.registerPodListerArgsForCall = append(fake.registerPodListerArgsForCall, struct { + arg1 string + arg2 v1.PodLister + }{arg1, arg2}) + fake.recordInvocation("RegisterPodLister", []interface{}{arg1, arg2}) + fake.registerPodListerMutex.Unlock() + if fake.RegisterPodListerStub != nil { + fake.RegisterPodListerStub(arg1, arg2) + } +} + +func (fake *FakeCoreV1Lister) RegisterPodListerCallCount() int { + fake.registerPodListerMutex.RLock() + defer fake.registerPodListerMutex.RUnlock() + return len(fake.registerPodListerArgsForCall) +} + +func (fake *FakeCoreV1Lister) RegisterPodListerCalls(stub func(string, v1.PodLister)) { + fake.registerPodListerMutex.Lock() + defer fake.registerPodListerMutex.Unlock() + fake.RegisterPodListerStub = stub +} + +func (fake *FakeCoreV1Lister) RegisterPodListerArgsForCall(i int) (string, v1.PodLister) { + fake.registerPodListerMutex.RLock() + defer fake.registerPodListerMutex.RUnlock() + argsForCall := fake.registerPodListerArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2 +} + +func (fake *FakeCoreV1Lister) RegisterSecretLister(arg1 string, arg2 v1.SecretLister) { + fake.registerSecretListerMutex.Lock() + fake.registerSecretListerArgsForCall = append(fake.registerSecretListerArgsForCall, struct { + arg1 string + arg2 v1.SecretLister + }{arg1, arg2}) + fake.recordInvocation("RegisterSecretLister", []interface{}{arg1, arg2}) + fake.registerSecretListerMutex.Unlock() + if fake.RegisterSecretListerStub != nil { + fake.RegisterSecretListerStub(arg1, arg2) + } +} + +func (fake *FakeCoreV1Lister) RegisterSecretListerCallCount() int { + fake.registerSecretListerMutex.RLock() + defer fake.registerSecretListerMutex.RUnlock() + return len(fake.registerSecretListerArgsForCall) +} + +func (fake *FakeCoreV1Lister) RegisterSecretListerCalls(stub func(string, v1.SecretLister)) { + fake.registerSecretListerMutex.Lock() + defer fake.registerSecretListerMutex.Unlock() + fake.RegisterSecretListerStub = stub +} + +func (fake *FakeCoreV1Lister) RegisterSecretListerArgsForCall(i int) (string, v1.SecretLister) { + fake.registerSecretListerMutex.RLock() + defer fake.registerSecretListerMutex.RUnlock() + argsForCall := fake.registerSecretListerArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2 +} + +func (fake *FakeCoreV1Lister) RegisterServiceAccountLister(arg1 string, arg2 v1.ServiceAccountLister) { + fake.registerServiceAccountListerMutex.Lock() + fake.registerServiceAccountListerArgsForCall = append(fake.registerServiceAccountListerArgsForCall, struct { + arg1 string + arg2 v1.ServiceAccountLister + }{arg1, arg2}) + fake.recordInvocation("RegisterServiceAccountLister", []interface{}{arg1, arg2}) + fake.registerServiceAccountListerMutex.Unlock() + if fake.RegisterServiceAccountListerStub != nil { + fake.RegisterServiceAccountListerStub(arg1, arg2) + } +} + +func (fake *FakeCoreV1Lister) RegisterServiceAccountListerCallCount() int { + fake.registerServiceAccountListerMutex.RLock() + defer fake.registerServiceAccountListerMutex.RUnlock() + return len(fake.registerServiceAccountListerArgsForCall) +} + +func (fake *FakeCoreV1Lister) RegisterServiceAccountListerCalls(stub func(string, v1.ServiceAccountLister)) { + fake.registerServiceAccountListerMutex.Lock() + defer fake.registerServiceAccountListerMutex.Unlock() + fake.RegisterServiceAccountListerStub = stub +} + +func (fake *FakeCoreV1Lister) RegisterServiceAccountListerArgsForCall(i int) (string, v1.ServiceAccountLister) { + fake.registerServiceAccountListerMutex.RLock() + defer fake.registerServiceAccountListerMutex.RUnlock() + argsForCall := fake.registerServiceAccountListerArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2 +} + +func (fake *FakeCoreV1Lister) RegisterServiceLister(arg1 string, arg2 v1.ServiceLister) { + fake.registerServiceListerMutex.Lock() + fake.registerServiceListerArgsForCall = append(fake.registerServiceListerArgsForCall, struct { + arg1 string + arg2 v1.ServiceLister + }{arg1, arg2}) + fake.recordInvocation("RegisterServiceLister", []interface{}{arg1, arg2}) + fake.registerServiceListerMutex.Unlock() + if fake.RegisterServiceListerStub != nil { + fake.RegisterServiceListerStub(arg1, arg2) + } +} + +func (fake *FakeCoreV1Lister) RegisterServiceListerCallCount() int { + fake.registerServiceListerMutex.RLock() + defer fake.registerServiceListerMutex.RUnlock() + return len(fake.registerServiceListerArgsForCall) +} + +func (fake *FakeCoreV1Lister) RegisterServiceListerCalls(stub func(string, v1.ServiceLister)) { + fake.registerServiceListerMutex.Lock() + defer fake.registerServiceListerMutex.Unlock() + fake.RegisterServiceListerStub = stub +} + +func (fake *FakeCoreV1Lister) RegisterServiceListerArgsForCall(i int) (string, v1.ServiceLister) { + fake.registerServiceListerMutex.RLock() + defer fake.registerServiceListerMutex.RUnlock() + argsForCall := fake.registerServiceListerArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2 +} + +func (fake *FakeCoreV1Lister) SecretLister() v1.SecretLister { + fake.secretListerMutex.Lock() + ret, specificReturn := fake.secretListerReturnsOnCall[len(fake.secretListerArgsForCall)] + fake.secretListerArgsForCall = append(fake.secretListerArgsForCall, struct { + }{}) + fake.recordInvocation("SecretLister", []interface{}{}) + fake.secretListerMutex.Unlock() + if fake.SecretListerStub != nil { + return fake.SecretListerStub() + } + if specificReturn { + return ret.result1 + } + fakeReturns := fake.secretListerReturns + return fakeReturns.result1 +} + +func (fake *FakeCoreV1Lister) SecretListerCallCount() int { + fake.secretListerMutex.RLock() + defer fake.secretListerMutex.RUnlock() + return len(fake.secretListerArgsForCall) +} + +func (fake *FakeCoreV1Lister) SecretListerCalls(stub func() v1.SecretLister) { + fake.secretListerMutex.Lock() + defer fake.secretListerMutex.Unlock() + fake.SecretListerStub = stub +} + +func (fake *FakeCoreV1Lister) SecretListerReturns(result1 v1.SecretLister) { + fake.secretListerMutex.Lock() + defer fake.secretListerMutex.Unlock() + fake.SecretListerStub = nil + fake.secretListerReturns = struct { + result1 v1.SecretLister + }{result1} +} + +func (fake *FakeCoreV1Lister) SecretListerReturnsOnCall(i int, result1 v1.SecretLister) { + fake.secretListerMutex.Lock() + defer fake.secretListerMutex.Unlock() + fake.SecretListerStub = nil + if fake.secretListerReturnsOnCall == nil { + fake.secretListerReturnsOnCall = make(map[int]struct { + result1 v1.SecretLister + }) + } + fake.secretListerReturnsOnCall[i] = struct { + result1 v1.SecretLister + }{result1} +} + +func (fake *FakeCoreV1Lister) ServiceAccountLister() v1.ServiceAccountLister { + fake.serviceAccountListerMutex.Lock() + ret, specificReturn := fake.serviceAccountListerReturnsOnCall[len(fake.serviceAccountListerArgsForCall)] + fake.serviceAccountListerArgsForCall = append(fake.serviceAccountListerArgsForCall, struct { + }{}) + fake.recordInvocation("ServiceAccountLister", []interface{}{}) + fake.serviceAccountListerMutex.Unlock() + if fake.ServiceAccountListerStub != nil { + return fake.ServiceAccountListerStub() + } + if specificReturn { + return ret.result1 + } + fakeReturns := fake.serviceAccountListerReturns + return fakeReturns.result1 +} + +func (fake *FakeCoreV1Lister) ServiceAccountListerCallCount() int { + fake.serviceAccountListerMutex.RLock() + defer fake.serviceAccountListerMutex.RUnlock() + return len(fake.serviceAccountListerArgsForCall) +} + +func (fake *FakeCoreV1Lister) ServiceAccountListerCalls(stub func() v1.ServiceAccountLister) { + fake.serviceAccountListerMutex.Lock() + defer fake.serviceAccountListerMutex.Unlock() + fake.ServiceAccountListerStub = stub +} + +func (fake *FakeCoreV1Lister) ServiceAccountListerReturns(result1 v1.ServiceAccountLister) { + fake.serviceAccountListerMutex.Lock() + defer fake.serviceAccountListerMutex.Unlock() + fake.ServiceAccountListerStub = nil + fake.serviceAccountListerReturns = struct { + result1 v1.ServiceAccountLister + }{result1} +} + +func (fake *FakeCoreV1Lister) ServiceAccountListerReturnsOnCall(i int, result1 v1.ServiceAccountLister) { + fake.serviceAccountListerMutex.Lock() + defer fake.serviceAccountListerMutex.Unlock() + fake.ServiceAccountListerStub = nil + if fake.serviceAccountListerReturnsOnCall == nil { + fake.serviceAccountListerReturnsOnCall = make(map[int]struct { + result1 v1.ServiceAccountLister + }) + } + fake.serviceAccountListerReturnsOnCall[i] = struct { + result1 v1.ServiceAccountLister + }{result1} +} + +func (fake *FakeCoreV1Lister) ServiceLister() v1.ServiceLister { + fake.serviceListerMutex.Lock() + ret, specificReturn := fake.serviceListerReturnsOnCall[len(fake.serviceListerArgsForCall)] + fake.serviceListerArgsForCall = append(fake.serviceListerArgsForCall, struct { + }{}) + fake.recordInvocation("ServiceLister", []interface{}{}) + fake.serviceListerMutex.Unlock() + if fake.ServiceListerStub != nil { + return fake.ServiceListerStub() + } + if specificReturn { + return ret.result1 + } + fakeReturns := fake.serviceListerReturns + return fakeReturns.result1 +} + +func (fake *FakeCoreV1Lister) ServiceListerCallCount() int { + fake.serviceListerMutex.RLock() + defer fake.serviceListerMutex.RUnlock() + return len(fake.serviceListerArgsForCall) +} + +func (fake *FakeCoreV1Lister) ServiceListerCalls(stub func() v1.ServiceLister) { + fake.serviceListerMutex.Lock() + defer fake.serviceListerMutex.Unlock() + fake.ServiceListerStub = stub +} + +func (fake *FakeCoreV1Lister) ServiceListerReturns(result1 v1.ServiceLister) { + fake.serviceListerMutex.Lock() + defer fake.serviceListerMutex.Unlock() + fake.ServiceListerStub = nil + fake.serviceListerReturns = struct { + result1 v1.ServiceLister + }{result1} +} + +func (fake *FakeCoreV1Lister) ServiceListerReturnsOnCall(i int, result1 v1.ServiceLister) { + fake.serviceListerMutex.Lock() + defer fake.serviceListerMutex.Unlock() + fake.ServiceListerStub = nil + if fake.serviceListerReturnsOnCall == nil { + fake.serviceListerReturnsOnCall = make(map[int]struct { + result1 v1.ServiceLister + }) + } + fake.serviceListerReturnsOnCall[i] = struct { + result1 v1.ServiceLister + }{result1} +} + +func (fake *FakeCoreV1Lister) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.configMapListerMutex.RLock() + defer fake.configMapListerMutex.RUnlock() + fake.namespaceListerMutex.RLock() + defer fake.namespaceListerMutex.RUnlock() + fake.podListerMutex.RLock() + defer fake.podListerMutex.RUnlock() + fake.registerConfigMapListerMutex.RLock() + defer fake.registerConfigMapListerMutex.RUnlock() + fake.registerNamespaceListerMutex.RLock() + defer fake.registerNamespaceListerMutex.RUnlock() + fake.registerPodListerMutex.RLock() + defer fake.registerPodListerMutex.RUnlock() + fake.registerSecretListerMutex.RLock() + defer fake.registerSecretListerMutex.RUnlock() + fake.registerServiceAccountListerMutex.RLock() + defer fake.registerServiceAccountListerMutex.RUnlock() + fake.registerServiceListerMutex.RLock() + defer fake.registerServiceListerMutex.RUnlock() + fake.secretListerMutex.RLock() + defer fake.secretListerMutex.RUnlock() + fake.serviceAccountListerMutex.RLock() + defer fake.serviceAccountListerMutex.RUnlock() + fake.serviceListerMutex.RLock() + defer fake.serviceListerMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *FakeCoreV1Lister) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} + +var _ operatorlister.CoreV1Lister = new(FakeCoreV1Lister) diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/operatorlisterfakes/fake_operator_lister.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/operatorlisterfakes/fake_operator_lister.go new file mode 100644 index 0000000000..9f90da69e1 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/operatorlisterfakes/fake_operator_lister.go @@ -0,0 +1,485 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package operatorlisterfakes + +import ( + sync "sync" + + operatorlister "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister" +) + +type FakeOperatorLister struct { + APIExtensionsV1beta1Stub func() operatorlister.APIExtensionsV1beta1Lister + aPIExtensionsV1beta1Mutex sync.RWMutex + aPIExtensionsV1beta1ArgsForCall []struct { + } + aPIExtensionsV1beta1Returns struct { + result1 operatorlister.APIExtensionsV1beta1Lister + } + aPIExtensionsV1beta1ReturnsOnCall map[int]struct { + result1 operatorlister.APIExtensionsV1beta1Lister + } + APIRegistrationV1Stub func() operatorlister.APIRegistrationV1Lister + aPIRegistrationV1Mutex sync.RWMutex + aPIRegistrationV1ArgsForCall []struct { + } + aPIRegistrationV1Returns struct { + result1 operatorlister.APIRegistrationV1Lister + } + aPIRegistrationV1ReturnsOnCall map[int]struct { + result1 operatorlister.APIRegistrationV1Lister + } + AppsV1Stub func() operatorlister.AppsV1Lister + appsV1Mutex sync.RWMutex + appsV1ArgsForCall []struct { + } + appsV1Returns struct { + result1 operatorlister.AppsV1Lister + } + appsV1ReturnsOnCall map[int]struct { + result1 operatorlister.AppsV1Lister + } + CoreV1Stub func() operatorlister.CoreV1Lister + coreV1Mutex sync.RWMutex + coreV1ArgsForCall []struct { + } + coreV1Returns struct { + result1 operatorlister.CoreV1Lister + } + coreV1ReturnsOnCall map[int]struct { + result1 operatorlister.CoreV1Lister + } + OperatorsV1Stub func() operatorlister.OperatorsV1Lister + operatorsV1Mutex sync.RWMutex + operatorsV1ArgsForCall []struct { + } + operatorsV1Returns struct { + result1 operatorlister.OperatorsV1Lister + } + operatorsV1ReturnsOnCall map[int]struct { + result1 operatorlister.OperatorsV1Lister + } + OperatorsV1alpha1Stub func() operatorlister.OperatorsV1alpha1Lister + operatorsV1alpha1Mutex sync.RWMutex + operatorsV1alpha1ArgsForCall []struct { + } + operatorsV1alpha1Returns struct { + result1 operatorlister.OperatorsV1alpha1Lister + } + operatorsV1alpha1ReturnsOnCall map[int]struct { + result1 operatorlister.OperatorsV1alpha1Lister + } + RbacV1Stub func() operatorlister.RbacV1Lister + rbacV1Mutex sync.RWMutex + rbacV1ArgsForCall []struct { + } + rbacV1Returns struct { + result1 operatorlister.RbacV1Lister + } + rbacV1ReturnsOnCall map[int]struct { + result1 operatorlister.RbacV1Lister + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *FakeOperatorLister) APIExtensionsV1beta1() operatorlister.APIExtensionsV1beta1Lister { + fake.aPIExtensionsV1beta1Mutex.Lock() + ret, specificReturn := fake.aPIExtensionsV1beta1ReturnsOnCall[len(fake.aPIExtensionsV1beta1ArgsForCall)] + fake.aPIExtensionsV1beta1ArgsForCall = append(fake.aPIExtensionsV1beta1ArgsForCall, struct { + }{}) + fake.recordInvocation("APIExtensionsV1beta1", []interface{}{}) + fake.aPIExtensionsV1beta1Mutex.Unlock() + if fake.APIExtensionsV1beta1Stub != nil { + return fake.APIExtensionsV1beta1Stub() + } + if specificReturn { + return ret.result1 + } + fakeReturns := fake.aPIExtensionsV1beta1Returns + return fakeReturns.result1 +} + +func (fake *FakeOperatorLister) APIExtensionsV1beta1CallCount() int { + fake.aPIExtensionsV1beta1Mutex.RLock() + defer fake.aPIExtensionsV1beta1Mutex.RUnlock() + return len(fake.aPIExtensionsV1beta1ArgsForCall) +} + +func (fake *FakeOperatorLister) APIExtensionsV1beta1Calls(stub func() operatorlister.APIExtensionsV1beta1Lister) { + fake.aPIExtensionsV1beta1Mutex.Lock() + defer fake.aPIExtensionsV1beta1Mutex.Unlock() + fake.APIExtensionsV1beta1Stub = stub +} + +func (fake *FakeOperatorLister) APIExtensionsV1beta1Returns(result1 operatorlister.APIExtensionsV1beta1Lister) { + fake.aPIExtensionsV1beta1Mutex.Lock() + defer fake.aPIExtensionsV1beta1Mutex.Unlock() + fake.APIExtensionsV1beta1Stub = nil + fake.aPIExtensionsV1beta1Returns = struct { + result1 operatorlister.APIExtensionsV1beta1Lister + }{result1} +} + +func (fake *FakeOperatorLister) APIExtensionsV1beta1ReturnsOnCall(i int, result1 operatorlister.APIExtensionsV1beta1Lister) { + fake.aPIExtensionsV1beta1Mutex.Lock() + defer fake.aPIExtensionsV1beta1Mutex.Unlock() + fake.APIExtensionsV1beta1Stub = nil + if fake.aPIExtensionsV1beta1ReturnsOnCall == nil { + fake.aPIExtensionsV1beta1ReturnsOnCall = make(map[int]struct { + result1 operatorlister.APIExtensionsV1beta1Lister + }) + } + fake.aPIExtensionsV1beta1ReturnsOnCall[i] = struct { + result1 operatorlister.APIExtensionsV1beta1Lister + }{result1} +} + +func (fake *FakeOperatorLister) APIRegistrationV1() operatorlister.APIRegistrationV1Lister { + fake.aPIRegistrationV1Mutex.Lock() + ret, specificReturn := fake.aPIRegistrationV1ReturnsOnCall[len(fake.aPIRegistrationV1ArgsForCall)] + fake.aPIRegistrationV1ArgsForCall = append(fake.aPIRegistrationV1ArgsForCall, struct { + }{}) + fake.recordInvocation("APIRegistrationV1", []interface{}{}) + fake.aPIRegistrationV1Mutex.Unlock() + if fake.APIRegistrationV1Stub != nil { + return fake.APIRegistrationV1Stub() + } + if specificReturn { + return ret.result1 + } + fakeReturns := fake.aPIRegistrationV1Returns + return fakeReturns.result1 +} + +func (fake *FakeOperatorLister) APIRegistrationV1CallCount() int { + fake.aPIRegistrationV1Mutex.RLock() + defer fake.aPIRegistrationV1Mutex.RUnlock() + return len(fake.aPIRegistrationV1ArgsForCall) +} + +func (fake *FakeOperatorLister) APIRegistrationV1Calls(stub func() operatorlister.APIRegistrationV1Lister) { + fake.aPIRegistrationV1Mutex.Lock() + defer fake.aPIRegistrationV1Mutex.Unlock() + fake.APIRegistrationV1Stub = stub +} + +func (fake *FakeOperatorLister) APIRegistrationV1Returns(result1 operatorlister.APIRegistrationV1Lister) { + fake.aPIRegistrationV1Mutex.Lock() + defer fake.aPIRegistrationV1Mutex.Unlock() + fake.APIRegistrationV1Stub = nil + fake.aPIRegistrationV1Returns = struct { + result1 operatorlister.APIRegistrationV1Lister + }{result1} +} + +func (fake *FakeOperatorLister) APIRegistrationV1ReturnsOnCall(i int, result1 operatorlister.APIRegistrationV1Lister) { + fake.aPIRegistrationV1Mutex.Lock() + defer fake.aPIRegistrationV1Mutex.Unlock() + fake.APIRegistrationV1Stub = nil + if fake.aPIRegistrationV1ReturnsOnCall == nil { + fake.aPIRegistrationV1ReturnsOnCall = make(map[int]struct { + result1 operatorlister.APIRegistrationV1Lister + }) + } + fake.aPIRegistrationV1ReturnsOnCall[i] = struct { + result1 operatorlister.APIRegistrationV1Lister + }{result1} +} + +func (fake *FakeOperatorLister) AppsV1() operatorlister.AppsV1Lister { + fake.appsV1Mutex.Lock() + ret, specificReturn := fake.appsV1ReturnsOnCall[len(fake.appsV1ArgsForCall)] + fake.appsV1ArgsForCall = append(fake.appsV1ArgsForCall, struct { + }{}) + fake.recordInvocation("AppsV1", []interface{}{}) + fake.appsV1Mutex.Unlock() + if fake.AppsV1Stub != nil { + return fake.AppsV1Stub() + } + if specificReturn { + return ret.result1 + } + fakeReturns := fake.appsV1Returns + return fakeReturns.result1 +} + +func (fake *FakeOperatorLister) AppsV1CallCount() int { + fake.appsV1Mutex.RLock() + defer fake.appsV1Mutex.RUnlock() + return len(fake.appsV1ArgsForCall) +} + +func (fake *FakeOperatorLister) AppsV1Calls(stub func() operatorlister.AppsV1Lister) { + fake.appsV1Mutex.Lock() + defer fake.appsV1Mutex.Unlock() + fake.AppsV1Stub = stub +} + +func (fake *FakeOperatorLister) AppsV1Returns(result1 operatorlister.AppsV1Lister) { + fake.appsV1Mutex.Lock() + defer fake.appsV1Mutex.Unlock() + fake.AppsV1Stub = nil + fake.appsV1Returns = struct { + result1 operatorlister.AppsV1Lister + }{result1} +} + +func (fake *FakeOperatorLister) AppsV1ReturnsOnCall(i int, result1 operatorlister.AppsV1Lister) { + fake.appsV1Mutex.Lock() + defer fake.appsV1Mutex.Unlock() + fake.AppsV1Stub = nil + if fake.appsV1ReturnsOnCall == nil { + fake.appsV1ReturnsOnCall = make(map[int]struct { + result1 operatorlister.AppsV1Lister + }) + } + fake.appsV1ReturnsOnCall[i] = struct { + result1 operatorlister.AppsV1Lister + }{result1} +} + +func (fake *FakeOperatorLister) CoreV1() operatorlister.CoreV1Lister { + fake.coreV1Mutex.Lock() + ret, specificReturn := fake.coreV1ReturnsOnCall[len(fake.coreV1ArgsForCall)] + fake.coreV1ArgsForCall = append(fake.coreV1ArgsForCall, struct { + }{}) + fake.recordInvocation("CoreV1", []interface{}{}) + fake.coreV1Mutex.Unlock() + if fake.CoreV1Stub != nil { + return fake.CoreV1Stub() + } + if specificReturn { + return ret.result1 + } + fakeReturns := fake.coreV1Returns + return fakeReturns.result1 +} + +func (fake *FakeOperatorLister) CoreV1CallCount() int { + fake.coreV1Mutex.RLock() + defer fake.coreV1Mutex.RUnlock() + return len(fake.coreV1ArgsForCall) +} + +func (fake *FakeOperatorLister) CoreV1Calls(stub func() operatorlister.CoreV1Lister) { + fake.coreV1Mutex.Lock() + defer fake.coreV1Mutex.Unlock() + fake.CoreV1Stub = stub +} + +func (fake *FakeOperatorLister) CoreV1Returns(result1 operatorlister.CoreV1Lister) { + fake.coreV1Mutex.Lock() + defer fake.coreV1Mutex.Unlock() + fake.CoreV1Stub = nil + fake.coreV1Returns = struct { + result1 operatorlister.CoreV1Lister + }{result1} +} + +func (fake *FakeOperatorLister) CoreV1ReturnsOnCall(i int, result1 operatorlister.CoreV1Lister) { + fake.coreV1Mutex.Lock() + defer fake.coreV1Mutex.Unlock() + fake.CoreV1Stub = nil + if fake.coreV1ReturnsOnCall == nil { + fake.coreV1ReturnsOnCall = make(map[int]struct { + result1 operatorlister.CoreV1Lister + }) + } + fake.coreV1ReturnsOnCall[i] = struct { + result1 operatorlister.CoreV1Lister + }{result1} +} + +func (fake *FakeOperatorLister) OperatorsV1() operatorlister.OperatorsV1Lister { + fake.operatorsV1Mutex.Lock() + ret, specificReturn := fake.operatorsV1ReturnsOnCall[len(fake.operatorsV1ArgsForCall)] + fake.operatorsV1ArgsForCall = append(fake.operatorsV1ArgsForCall, struct { + }{}) + fake.recordInvocation("OperatorsV1", []interface{}{}) + fake.operatorsV1Mutex.Unlock() + if fake.OperatorsV1Stub != nil { + return fake.OperatorsV1Stub() + } + if specificReturn { + return ret.result1 + } + fakeReturns := fake.operatorsV1Returns + return fakeReturns.result1 +} + +func (fake *FakeOperatorLister) OperatorsV1CallCount() int { + fake.operatorsV1Mutex.RLock() + defer fake.operatorsV1Mutex.RUnlock() + return len(fake.operatorsV1ArgsForCall) +} + +func (fake *FakeOperatorLister) OperatorsV1Calls(stub func() operatorlister.OperatorsV1Lister) { + fake.operatorsV1Mutex.Lock() + defer fake.operatorsV1Mutex.Unlock() + fake.OperatorsV1Stub = stub +} + +func (fake *FakeOperatorLister) OperatorsV1Returns(result1 operatorlister.OperatorsV1Lister) { + fake.operatorsV1Mutex.Lock() + defer fake.operatorsV1Mutex.Unlock() + fake.OperatorsV1Stub = nil + fake.operatorsV1Returns = struct { + result1 operatorlister.OperatorsV1Lister + }{result1} +} + +func (fake *FakeOperatorLister) OperatorsV1ReturnsOnCall(i int, result1 operatorlister.OperatorsV1Lister) { + fake.operatorsV1Mutex.Lock() + defer fake.operatorsV1Mutex.Unlock() + fake.OperatorsV1Stub = nil + if fake.operatorsV1ReturnsOnCall == nil { + fake.operatorsV1ReturnsOnCall = make(map[int]struct { + result1 operatorlister.OperatorsV1Lister + }) + } + fake.operatorsV1ReturnsOnCall[i] = struct { + result1 operatorlister.OperatorsV1Lister + }{result1} +} + +func (fake *FakeOperatorLister) OperatorsV1alpha1() operatorlister.OperatorsV1alpha1Lister { + fake.operatorsV1alpha1Mutex.Lock() + ret, specificReturn := fake.operatorsV1alpha1ReturnsOnCall[len(fake.operatorsV1alpha1ArgsForCall)] + fake.operatorsV1alpha1ArgsForCall = append(fake.operatorsV1alpha1ArgsForCall, struct { + }{}) + fake.recordInvocation("OperatorsV1alpha1", []interface{}{}) + fake.operatorsV1alpha1Mutex.Unlock() + if fake.OperatorsV1alpha1Stub != nil { + return fake.OperatorsV1alpha1Stub() + } + if specificReturn { + return ret.result1 + } + fakeReturns := fake.operatorsV1alpha1Returns + return fakeReturns.result1 +} + +func (fake *FakeOperatorLister) OperatorsV1alpha1CallCount() int { + fake.operatorsV1alpha1Mutex.RLock() + defer fake.operatorsV1alpha1Mutex.RUnlock() + return len(fake.operatorsV1alpha1ArgsForCall) +} + +func (fake *FakeOperatorLister) OperatorsV1alpha1Calls(stub func() operatorlister.OperatorsV1alpha1Lister) { + fake.operatorsV1alpha1Mutex.Lock() + defer fake.operatorsV1alpha1Mutex.Unlock() + fake.OperatorsV1alpha1Stub = stub +} + +func (fake *FakeOperatorLister) OperatorsV1alpha1Returns(result1 operatorlister.OperatorsV1alpha1Lister) { + fake.operatorsV1alpha1Mutex.Lock() + defer fake.operatorsV1alpha1Mutex.Unlock() + fake.OperatorsV1alpha1Stub = nil + fake.operatorsV1alpha1Returns = struct { + result1 operatorlister.OperatorsV1alpha1Lister + }{result1} +} + +func (fake *FakeOperatorLister) OperatorsV1alpha1ReturnsOnCall(i int, result1 operatorlister.OperatorsV1alpha1Lister) { + fake.operatorsV1alpha1Mutex.Lock() + defer fake.operatorsV1alpha1Mutex.Unlock() + fake.OperatorsV1alpha1Stub = nil + if fake.operatorsV1alpha1ReturnsOnCall == nil { + fake.operatorsV1alpha1ReturnsOnCall = make(map[int]struct { + result1 operatorlister.OperatorsV1alpha1Lister + }) + } + fake.operatorsV1alpha1ReturnsOnCall[i] = struct { + result1 operatorlister.OperatorsV1alpha1Lister + }{result1} +} + +func (fake *FakeOperatorLister) RbacV1() operatorlister.RbacV1Lister { + fake.rbacV1Mutex.Lock() + ret, specificReturn := fake.rbacV1ReturnsOnCall[len(fake.rbacV1ArgsForCall)] + fake.rbacV1ArgsForCall = append(fake.rbacV1ArgsForCall, struct { + }{}) + fake.recordInvocation("RbacV1", []interface{}{}) + fake.rbacV1Mutex.Unlock() + if fake.RbacV1Stub != nil { + return fake.RbacV1Stub() + } + if specificReturn { + return ret.result1 + } + fakeReturns := fake.rbacV1Returns + return fakeReturns.result1 +} + +func (fake *FakeOperatorLister) RbacV1CallCount() int { + fake.rbacV1Mutex.RLock() + defer fake.rbacV1Mutex.RUnlock() + return len(fake.rbacV1ArgsForCall) +} + +func (fake *FakeOperatorLister) RbacV1Calls(stub func() operatorlister.RbacV1Lister) { + fake.rbacV1Mutex.Lock() + defer fake.rbacV1Mutex.Unlock() + fake.RbacV1Stub = stub +} + +func (fake *FakeOperatorLister) RbacV1Returns(result1 operatorlister.RbacV1Lister) { + fake.rbacV1Mutex.Lock() + defer fake.rbacV1Mutex.Unlock() + fake.RbacV1Stub = nil + fake.rbacV1Returns = struct { + result1 operatorlister.RbacV1Lister + }{result1} +} + +func (fake *FakeOperatorLister) RbacV1ReturnsOnCall(i int, result1 operatorlister.RbacV1Lister) { + fake.rbacV1Mutex.Lock() + defer fake.rbacV1Mutex.Unlock() + fake.RbacV1Stub = nil + if fake.rbacV1ReturnsOnCall == nil { + fake.rbacV1ReturnsOnCall = make(map[int]struct { + result1 operatorlister.RbacV1Lister + }) + } + fake.rbacV1ReturnsOnCall[i] = struct { + result1 operatorlister.RbacV1Lister + }{result1} +} + +func (fake *FakeOperatorLister) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.aPIExtensionsV1beta1Mutex.RLock() + defer fake.aPIExtensionsV1beta1Mutex.RUnlock() + fake.aPIRegistrationV1Mutex.RLock() + defer fake.aPIRegistrationV1Mutex.RUnlock() + fake.appsV1Mutex.RLock() + defer fake.appsV1Mutex.RUnlock() + fake.coreV1Mutex.RLock() + defer fake.coreV1Mutex.RUnlock() + fake.operatorsV1Mutex.RLock() + defer fake.operatorsV1Mutex.RUnlock() + fake.operatorsV1alpha1Mutex.RLock() + defer fake.operatorsV1alpha1Mutex.RUnlock() + fake.rbacV1Mutex.RLock() + defer fake.rbacV1Mutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *FakeOperatorLister) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} + +var _ operatorlister.OperatorLister = new(FakeOperatorLister) diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/operatorlisterfakes/fake_operators_v1alpha1lister.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/operatorlisterfakes/fake_operators_v1alpha1lister.go new file mode 100644 index 0000000000..03db90b01c --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/operatorlisterfakes/fake_operators_v1alpha1lister.go @@ -0,0 +1,350 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package operatorlisterfakes + +import ( + sync "sync" + + v1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1alpha1" + operatorlister "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister" +) + +type FakeOperatorsV1alpha1Lister struct { + ClusterServiceVersionListerStub func() v1alpha1.ClusterServiceVersionLister + clusterServiceVersionListerMutex sync.RWMutex + clusterServiceVersionListerArgsForCall []struct { + } + clusterServiceVersionListerReturns struct { + result1 v1alpha1.ClusterServiceVersionLister + } + clusterServiceVersionListerReturnsOnCall map[int]struct { + result1 v1alpha1.ClusterServiceVersionLister + } + InstallPlanListerStub func() v1alpha1.InstallPlanLister + installPlanListerMutex sync.RWMutex + installPlanListerArgsForCall []struct { + } + installPlanListerReturns struct { + result1 v1alpha1.InstallPlanLister + } + installPlanListerReturnsOnCall map[int]struct { + result1 v1alpha1.InstallPlanLister + } + RegisterClusterServiceVersionListerStub func(string, v1alpha1.ClusterServiceVersionLister) + registerClusterServiceVersionListerMutex sync.RWMutex + registerClusterServiceVersionListerArgsForCall []struct { + arg1 string + arg2 v1alpha1.ClusterServiceVersionLister + } + RegisterInstallPlanListerStub func(string, v1alpha1.InstallPlanLister) + registerInstallPlanListerMutex sync.RWMutex + registerInstallPlanListerArgsForCall []struct { + arg1 string + arg2 v1alpha1.InstallPlanLister + } + RegisterSubscriptionListerStub func(string, v1alpha1.SubscriptionLister) + registerSubscriptionListerMutex sync.RWMutex + registerSubscriptionListerArgsForCall []struct { + arg1 string + arg2 v1alpha1.SubscriptionLister + } + SubscriptionListerStub func() v1alpha1.SubscriptionLister + subscriptionListerMutex sync.RWMutex + subscriptionListerArgsForCall []struct { + } + subscriptionListerReturns struct { + result1 v1alpha1.SubscriptionLister + } + subscriptionListerReturnsOnCall map[int]struct { + result1 v1alpha1.SubscriptionLister + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *FakeOperatorsV1alpha1Lister) ClusterServiceVersionLister() v1alpha1.ClusterServiceVersionLister { + fake.clusterServiceVersionListerMutex.Lock() + ret, specificReturn := fake.clusterServiceVersionListerReturnsOnCall[len(fake.clusterServiceVersionListerArgsForCall)] + fake.clusterServiceVersionListerArgsForCall = append(fake.clusterServiceVersionListerArgsForCall, struct { + }{}) + fake.recordInvocation("ClusterServiceVersionLister", []interface{}{}) + fake.clusterServiceVersionListerMutex.Unlock() + if fake.ClusterServiceVersionListerStub != nil { + return fake.ClusterServiceVersionListerStub() + } + if specificReturn { + return ret.result1 + } + fakeReturns := fake.clusterServiceVersionListerReturns + return fakeReturns.result1 +} + +func (fake *FakeOperatorsV1alpha1Lister) ClusterServiceVersionListerCallCount() int { + fake.clusterServiceVersionListerMutex.RLock() + defer fake.clusterServiceVersionListerMutex.RUnlock() + return len(fake.clusterServiceVersionListerArgsForCall) +} + +func (fake *FakeOperatorsV1alpha1Lister) ClusterServiceVersionListerCalls(stub func() v1alpha1.ClusterServiceVersionLister) { + fake.clusterServiceVersionListerMutex.Lock() + defer fake.clusterServiceVersionListerMutex.Unlock() + fake.ClusterServiceVersionListerStub = stub +} + +func (fake *FakeOperatorsV1alpha1Lister) ClusterServiceVersionListerReturns(result1 v1alpha1.ClusterServiceVersionLister) { + fake.clusterServiceVersionListerMutex.Lock() + defer fake.clusterServiceVersionListerMutex.Unlock() + fake.ClusterServiceVersionListerStub = nil + fake.clusterServiceVersionListerReturns = struct { + result1 v1alpha1.ClusterServiceVersionLister + }{result1} +} + +func (fake *FakeOperatorsV1alpha1Lister) ClusterServiceVersionListerReturnsOnCall(i int, result1 v1alpha1.ClusterServiceVersionLister) { + fake.clusterServiceVersionListerMutex.Lock() + defer fake.clusterServiceVersionListerMutex.Unlock() + fake.ClusterServiceVersionListerStub = nil + if fake.clusterServiceVersionListerReturnsOnCall == nil { + fake.clusterServiceVersionListerReturnsOnCall = make(map[int]struct { + result1 v1alpha1.ClusterServiceVersionLister + }) + } + fake.clusterServiceVersionListerReturnsOnCall[i] = struct { + result1 v1alpha1.ClusterServiceVersionLister + }{result1} +} + +func (fake *FakeOperatorsV1alpha1Lister) InstallPlanLister() v1alpha1.InstallPlanLister { + fake.installPlanListerMutex.Lock() + ret, specificReturn := fake.installPlanListerReturnsOnCall[len(fake.installPlanListerArgsForCall)] + fake.installPlanListerArgsForCall = append(fake.installPlanListerArgsForCall, struct { + }{}) + fake.recordInvocation("InstallPlanLister", []interface{}{}) + fake.installPlanListerMutex.Unlock() + if fake.InstallPlanListerStub != nil { + return fake.InstallPlanListerStub() + } + if specificReturn { + return ret.result1 + } + fakeReturns := fake.installPlanListerReturns + return fakeReturns.result1 +} + +func (fake *FakeOperatorsV1alpha1Lister) InstallPlanListerCallCount() int { + fake.installPlanListerMutex.RLock() + defer fake.installPlanListerMutex.RUnlock() + return len(fake.installPlanListerArgsForCall) +} + +func (fake *FakeOperatorsV1alpha1Lister) InstallPlanListerCalls(stub func() v1alpha1.InstallPlanLister) { + fake.installPlanListerMutex.Lock() + defer fake.installPlanListerMutex.Unlock() + fake.InstallPlanListerStub = stub +} + +func (fake *FakeOperatorsV1alpha1Lister) InstallPlanListerReturns(result1 v1alpha1.InstallPlanLister) { + fake.installPlanListerMutex.Lock() + defer fake.installPlanListerMutex.Unlock() + fake.InstallPlanListerStub = nil + fake.installPlanListerReturns = struct { + result1 v1alpha1.InstallPlanLister + }{result1} +} + +func (fake *FakeOperatorsV1alpha1Lister) InstallPlanListerReturnsOnCall(i int, result1 v1alpha1.InstallPlanLister) { + fake.installPlanListerMutex.Lock() + defer fake.installPlanListerMutex.Unlock() + fake.InstallPlanListerStub = nil + if fake.installPlanListerReturnsOnCall == nil { + fake.installPlanListerReturnsOnCall = make(map[int]struct { + result1 v1alpha1.InstallPlanLister + }) + } + fake.installPlanListerReturnsOnCall[i] = struct { + result1 v1alpha1.InstallPlanLister + }{result1} +} + +func (fake *FakeOperatorsV1alpha1Lister) RegisterClusterServiceVersionLister(arg1 string, arg2 v1alpha1.ClusterServiceVersionLister) { + fake.registerClusterServiceVersionListerMutex.Lock() + fake.registerClusterServiceVersionListerArgsForCall = append(fake.registerClusterServiceVersionListerArgsForCall, struct { + arg1 string + arg2 v1alpha1.ClusterServiceVersionLister + }{arg1, arg2}) + fake.recordInvocation("RegisterClusterServiceVersionLister", []interface{}{arg1, arg2}) + fake.registerClusterServiceVersionListerMutex.Unlock() + if fake.RegisterClusterServiceVersionListerStub != nil { + fake.RegisterClusterServiceVersionListerStub(arg1, arg2) + } +} + +func (fake *FakeOperatorsV1alpha1Lister) RegisterClusterServiceVersionListerCallCount() int { + fake.registerClusterServiceVersionListerMutex.RLock() + defer fake.registerClusterServiceVersionListerMutex.RUnlock() + return len(fake.registerClusterServiceVersionListerArgsForCall) +} + +func (fake *FakeOperatorsV1alpha1Lister) RegisterClusterServiceVersionListerCalls(stub func(string, v1alpha1.ClusterServiceVersionLister)) { + fake.registerClusterServiceVersionListerMutex.Lock() + defer fake.registerClusterServiceVersionListerMutex.Unlock() + fake.RegisterClusterServiceVersionListerStub = stub +} + +func (fake *FakeOperatorsV1alpha1Lister) RegisterClusterServiceVersionListerArgsForCall(i int) (string, v1alpha1.ClusterServiceVersionLister) { + fake.registerClusterServiceVersionListerMutex.RLock() + defer fake.registerClusterServiceVersionListerMutex.RUnlock() + argsForCall := fake.registerClusterServiceVersionListerArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2 +} + +func (fake *FakeOperatorsV1alpha1Lister) RegisterInstallPlanLister(arg1 string, arg2 v1alpha1.InstallPlanLister) { + fake.registerInstallPlanListerMutex.Lock() + fake.registerInstallPlanListerArgsForCall = append(fake.registerInstallPlanListerArgsForCall, struct { + arg1 string + arg2 v1alpha1.InstallPlanLister + }{arg1, arg2}) + fake.recordInvocation("RegisterInstallPlanLister", []interface{}{arg1, arg2}) + fake.registerInstallPlanListerMutex.Unlock() + if fake.RegisterInstallPlanListerStub != nil { + fake.RegisterInstallPlanListerStub(arg1, arg2) + } +} + +func (fake *FakeOperatorsV1alpha1Lister) RegisterInstallPlanListerCallCount() int { + fake.registerInstallPlanListerMutex.RLock() + defer fake.registerInstallPlanListerMutex.RUnlock() + return len(fake.registerInstallPlanListerArgsForCall) +} + +func (fake *FakeOperatorsV1alpha1Lister) RegisterInstallPlanListerCalls(stub func(string, v1alpha1.InstallPlanLister)) { + fake.registerInstallPlanListerMutex.Lock() + defer fake.registerInstallPlanListerMutex.Unlock() + fake.RegisterInstallPlanListerStub = stub +} + +func (fake *FakeOperatorsV1alpha1Lister) RegisterInstallPlanListerArgsForCall(i int) (string, v1alpha1.InstallPlanLister) { + fake.registerInstallPlanListerMutex.RLock() + defer fake.registerInstallPlanListerMutex.RUnlock() + argsForCall := fake.registerInstallPlanListerArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2 +} + +func (fake *FakeOperatorsV1alpha1Lister) RegisterSubscriptionLister(arg1 string, arg2 v1alpha1.SubscriptionLister) { + fake.registerSubscriptionListerMutex.Lock() + fake.registerSubscriptionListerArgsForCall = append(fake.registerSubscriptionListerArgsForCall, struct { + arg1 string + arg2 v1alpha1.SubscriptionLister + }{arg1, arg2}) + fake.recordInvocation("RegisterSubscriptionLister", []interface{}{arg1, arg2}) + fake.registerSubscriptionListerMutex.Unlock() + if fake.RegisterSubscriptionListerStub != nil { + fake.RegisterSubscriptionListerStub(arg1, arg2) + } +} + +func (fake *FakeOperatorsV1alpha1Lister) RegisterSubscriptionListerCallCount() int { + fake.registerSubscriptionListerMutex.RLock() + defer fake.registerSubscriptionListerMutex.RUnlock() + return len(fake.registerSubscriptionListerArgsForCall) +} + +func (fake *FakeOperatorsV1alpha1Lister) RegisterSubscriptionListerCalls(stub func(string, v1alpha1.SubscriptionLister)) { + fake.registerSubscriptionListerMutex.Lock() + defer fake.registerSubscriptionListerMutex.Unlock() + fake.RegisterSubscriptionListerStub = stub +} + +func (fake *FakeOperatorsV1alpha1Lister) RegisterSubscriptionListerArgsForCall(i int) (string, v1alpha1.SubscriptionLister) { + fake.registerSubscriptionListerMutex.RLock() + defer fake.registerSubscriptionListerMutex.RUnlock() + argsForCall := fake.registerSubscriptionListerArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2 +} + +func (fake *FakeOperatorsV1alpha1Lister) SubscriptionLister() v1alpha1.SubscriptionLister { + fake.subscriptionListerMutex.Lock() + ret, specificReturn := fake.subscriptionListerReturnsOnCall[len(fake.subscriptionListerArgsForCall)] + fake.subscriptionListerArgsForCall = append(fake.subscriptionListerArgsForCall, struct { + }{}) + fake.recordInvocation("SubscriptionLister", []interface{}{}) + fake.subscriptionListerMutex.Unlock() + if fake.SubscriptionListerStub != nil { + return fake.SubscriptionListerStub() + } + if specificReturn { + return ret.result1 + } + fakeReturns := fake.subscriptionListerReturns + return fakeReturns.result1 +} + +func (fake *FakeOperatorsV1alpha1Lister) SubscriptionListerCallCount() int { + fake.subscriptionListerMutex.RLock() + defer fake.subscriptionListerMutex.RUnlock() + return len(fake.subscriptionListerArgsForCall) +} + +func (fake *FakeOperatorsV1alpha1Lister) SubscriptionListerCalls(stub func() v1alpha1.SubscriptionLister) { + fake.subscriptionListerMutex.Lock() + defer fake.subscriptionListerMutex.Unlock() + fake.SubscriptionListerStub = stub +} + +func (fake *FakeOperatorsV1alpha1Lister) SubscriptionListerReturns(result1 v1alpha1.SubscriptionLister) { + fake.subscriptionListerMutex.Lock() + defer fake.subscriptionListerMutex.Unlock() + fake.SubscriptionListerStub = nil + fake.subscriptionListerReturns = struct { + result1 v1alpha1.SubscriptionLister + }{result1} +} + +func (fake *FakeOperatorsV1alpha1Lister) SubscriptionListerReturnsOnCall(i int, result1 v1alpha1.SubscriptionLister) { + fake.subscriptionListerMutex.Lock() + defer fake.subscriptionListerMutex.Unlock() + fake.SubscriptionListerStub = nil + if fake.subscriptionListerReturnsOnCall == nil { + fake.subscriptionListerReturnsOnCall = make(map[int]struct { + result1 v1alpha1.SubscriptionLister + }) + } + fake.subscriptionListerReturnsOnCall[i] = struct { + result1 v1alpha1.SubscriptionLister + }{result1} +} + +func (fake *FakeOperatorsV1alpha1Lister) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.clusterServiceVersionListerMutex.RLock() + defer fake.clusterServiceVersionListerMutex.RUnlock() + fake.installPlanListerMutex.RLock() + defer fake.installPlanListerMutex.RUnlock() + fake.registerClusterServiceVersionListerMutex.RLock() + defer fake.registerClusterServiceVersionListerMutex.RUnlock() + fake.registerInstallPlanListerMutex.RLock() + defer fake.registerInstallPlanListerMutex.RUnlock() + fake.registerSubscriptionListerMutex.RLock() + defer fake.registerSubscriptionListerMutex.RUnlock() + fake.subscriptionListerMutex.RLock() + defer fake.subscriptionListerMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *FakeOperatorsV1alpha1Lister) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} + +var _ operatorlister.OperatorsV1alpha1Lister = new(FakeOperatorsV1alpha1Lister) diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/operatorlisterfakes/fake_operators_v1lister.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/operatorlisterfakes/fake_operators_v1lister.go new file mode 100644 index 0000000000..4f2df0684b --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/operatorlisterfakes/fake_operators_v1lister.go @@ -0,0 +1,142 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package operatorlisterfakes + +import ( + sync "sync" + + v1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1" + operatorlister "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister" +) + +type FakeOperatorsV1Lister struct { + OperatorGroupListerStub func() v1.OperatorGroupLister + operatorGroupListerMutex sync.RWMutex + operatorGroupListerArgsForCall []struct { + } + operatorGroupListerReturns struct { + result1 v1.OperatorGroupLister + } + operatorGroupListerReturnsOnCall map[int]struct { + result1 v1.OperatorGroupLister + } + RegisterOperatorGroupListerStub func(string, v1.OperatorGroupLister) + registerOperatorGroupListerMutex sync.RWMutex + registerOperatorGroupListerArgsForCall []struct { + arg1 string + arg2 v1.OperatorGroupLister + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *FakeOperatorsV1Lister) OperatorGroupLister() v1.OperatorGroupLister { + fake.operatorGroupListerMutex.Lock() + ret, specificReturn := fake.operatorGroupListerReturnsOnCall[len(fake.operatorGroupListerArgsForCall)] + fake.operatorGroupListerArgsForCall = append(fake.operatorGroupListerArgsForCall, struct { + }{}) + fake.recordInvocation("OperatorGroupLister", []interface{}{}) + fake.operatorGroupListerMutex.Unlock() + if fake.OperatorGroupListerStub != nil { + return fake.OperatorGroupListerStub() + } + if specificReturn { + return ret.result1 + } + fakeReturns := fake.operatorGroupListerReturns + return fakeReturns.result1 +} + +func (fake *FakeOperatorsV1Lister) OperatorGroupListerCallCount() int { + fake.operatorGroupListerMutex.RLock() + defer fake.operatorGroupListerMutex.RUnlock() + return len(fake.operatorGroupListerArgsForCall) +} + +func (fake *FakeOperatorsV1Lister) OperatorGroupListerCalls(stub func() v1.OperatorGroupLister) { + fake.operatorGroupListerMutex.Lock() + defer fake.operatorGroupListerMutex.Unlock() + fake.OperatorGroupListerStub = stub +} + +func (fake *FakeOperatorsV1Lister) OperatorGroupListerReturns(result1 v1.OperatorGroupLister) { + fake.operatorGroupListerMutex.Lock() + defer fake.operatorGroupListerMutex.Unlock() + fake.OperatorGroupListerStub = nil + fake.operatorGroupListerReturns = struct { + result1 v1.OperatorGroupLister + }{result1} +} + +func (fake *FakeOperatorsV1Lister) OperatorGroupListerReturnsOnCall(i int, result1 v1.OperatorGroupLister) { + fake.operatorGroupListerMutex.Lock() + defer fake.operatorGroupListerMutex.Unlock() + fake.OperatorGroupListerStub = nil + if fake.operatorGroupListerReturnsOnCall == nil { + fake.operatorGroupListerReturnsOnCall = make(map[int]struct { + result1 v1.OperatorGroupLister + }) + } + fake.operatorGroupListerReturnsOnCall[i] = struct { + result1 v1.OperatorGroupLister + }{result1} +} + +func (fake *FakeOperatorsV1Lister) RegisterOperatorGroupLister(arg1 string, arg2 v1.OperatorGroupLister) { + fake.registerOperatorGroupListerMutex.Lock() + fake.registerOperatorGroupListerArgsForCall = append(fake.registerOperatorGroupListerArgsForCall, struct { + arg1 string + arg2 v1.OperatorGroupLister + }{arg1, arg2}) + fake.recordInvocation("RegisterOperatorGroupLister", []interface{}{arg1, arg2}) + fake.registerOperatorGroupListerMutex.Unlock() + if fake.RegisterOperatorGroupListerStub != nil { + fake.RegisterOperatorGroupListerStub(arg1, arg2) + } +} + +func (fake *FakeOperatorsV1Lister) RegisterOperatorGroupListerCallCount() int { + fake.registerOperatorGroupListerMutex.RLock() + defer fake.registerOperatorGroupListerMutex.RUnlock() + return len(fake.registerOperatorGroupListerArgsForCall) +} + +func (fake *FakeOperatorsV1Lister) RegisterOperatorGroupListerCalls(stub func(string, v1.OperatorGroupLister)) { + fake.registerOperatorGroupListerMutex.Lock() + defer fake.registerOperatorGroupListerMutex.Unlock() + fake.RegisterOperatorGroupListerStub = stub +} + +func (fake *FakeOperatorsV1Lister) RegisterOperatorGroupListerArgsForCall(i int) (string, v1.OperatorGroupLister) { + fake.registerOperatorGroupListerMutex.RLock() + defer fake.registerOperatorGroupListerMutex.RUnlock() + argsForCall := fake.registerOperatorGroupListerArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2 +} + +func (fake *FakeOperatorsV1Lister) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.operatorGroupListerMutex.RLock() + defer fake.operatorGroupListerMutex.RUnlock() + fake.registerOperatorGroupListerMutex.RLock() + defer fake.registerOperatorGroupListerMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *FakeOperatorsV1Lister) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} + +var _ operatorlister.OperatorsV1Lister = new(FakeOperatorsV1Lister) diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/operatorlisterfakes/fake_rbac_v1lister.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/operatorlisterfakes/fake_rbac_v1lister.go new file mode 100644 index 0000000000..171d5d7b9e --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/operatorlisterfakes/fake_rbac_v1lister.go @@ -0,0 +1,450 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package operatorlisterfakes + +import ( + sync "sync" + + operatorlister "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister" + v1 "k8s.io/client-go/listers/rbac/v1" +) + +type FakeRbacV1Lister struct { + ClusterRoleBindingListerStub func() v1.ClusterRoleBindingLister + clusterRoleBindingListerMutex sync.RWMutex + clusterRoleBindingListerArgsForCall []struct { + } + clusterRoleBindingListerReturns struct { + result1 v1.ClusterRoleBindingLister + } + clusterRoleBindingListerReturnsOnCall map[int]struct { + result1 v1.ClusterRoleBindingLister + } + ClusterRoleListerStub func() v1.ClusterRoleLister + clusterRoleListerMutex sync.RWMutex + clusterRoleListerArgsForCall []struct { + } + clusterRoleListerReturns struct { + result1 v1.ClusterRoleLister + } + clusterRoleListerReturnsOnCall map[int]struct { + result1 v1.ClusterRoleLister + } + RegisterClusterRoleBindingListerStub func(v1.ClusterRoleBindingLister) + registerClusterRoleBindingListerMutex sync.RWMutex + registerClusterRoleBindingListerArgsForCall []struct { + arg1 v1.ClusterRoleBindingLister + } + RegisterClusterRoleListerStub func(v1.ClusterRoleLister) + registerClusterRoleListerMutex sync.RWMutex + registerClusterRoleListerArgsForCall []struct { + arg1 v1.ClusterRoleLister + } + RegisterRoleBindingListerStub func(string, v1.RoleBindingLister) + registerRoleBindingListerMutex sync.RWMutex + registerRoleBindingListerArgsForCall []struct { + arg1 string + arg2 v1.RoleBindingLister + } + RegisterRoleListerStub func(string, v1.RoleLister) + registerRoleListerMutex sync.RWMutex + registerRoleListerArgsForCall []struct { + arg1 string + arg2 v1.RoleLister + } + RoleBindingListerStub func() v1.RoleBindingLister + roleBindingListerMutex sync.RWMutex + roleBindingListerArgsForCall []struct { + } + roleBindingListerReturns struct { + result1 v1.RoleBindingLister + } + roleBindingListerReturnsOnCall map[int]struct { + result1 v1.RoleBindingLister + } + RoleListerStub func() v1.RoleLister + roleListerMutex sync.RWMutex + roleListerArgsForCall []struct { + } + roleListerReturns struct { + result1 v1.RoleLister + } + roleListerReturnsOnCall map[int]struct { + result1 v1.RoleLister + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *FakeRbacV1Lister) ClusterRoleBindingLister() v1.ClusterRoleBindingLister { + fake.clusterRoleBindingListerMutex.Lock() + ret, specificReturn := fake.clusterRoleBindingListerReturnsOnCall[len(fake.clusterRoleBindingListerArgsForCall)] + fake.clusterRoleBindingListerArgsForCall = append(fake.clusterRoleBindingListerArgsForCall, struct { + }{}) + fake.recordInvocation("ClusterRoleBindingLister", []interface{}{}) + fake.clusterRoleBindingListerMutex.Unlock() + if fake.ClusterRoleBindingListerStub != nil { + return fake.ClusterRoleBindingListerStub() + } + if specificReturn { + return ret.result1 + } + fakeReturns := fake.clusterRoleBindingListerReturns + return fakeReturns.result1 +} + +func (fake *FakeRbacV1Lister) ClusterRoleBindingListerCallCount() int { + fake.clusterRoleBindingListerMutex.RLock() + defer fake.clusterRoleBindingListerMutex.RUnlock() + return len(fake.clusterRoleBindingListerArgsForCall) +} + +func (fake *FakeRbacV1Lister) ClusterRoleBindingListerCalls(stub func() v1.ClusterRoleBindingLister) { + fake.clusterRoleBindingListerMutex.Lock() + defer fake.clusterRoleBindingListerMutex.Unlock() + fake.ClusterRoleBindingListerStub = stub +} + +func (fake *FakeRbacV1Lister) ClusterRoleBindingListerReturns(result1 v1.ClusterRoleBindingLister) { + fake.clusterRoleBindingListerMutex.Lock() + defer fake.clusterRoleBindingListerMutex.Unlock() + fake.ClusterRoleBindingListerStub = nil + fake.clusterRoleBindingListerReturns = struct { + result1 v1.ClusterRoleBindingLister + }{result1} +} + +func (fake *FakeRbacV1Lister) ClusterRoleBindingListerReturnsOnCall(i int, result1 v1.ClusterRoleBindingLister) { + fake.clusterRoleBindingListerMutex.Lock() + defer fake.clusterRoleBindingListerMutex.Unlock() + fake.ClusterRoleBindingListerStub = nil + if fake.clusterRoleBindingListerReturnsOnCall == nil { + fake.clusterRoleBindingListerReturnsOnCall = make(map[int]struct { + result1 v1.ClusterRoleBindingLister + }) + } + fake.clusterRoleBindingListerReturnsOnCall[i] = struct { + result1 v1.ClusterRoleBindingLister + }{result1} +} + +func (fake *FakeRbacV1Lister) ClusterRoleLister() v1.ClusterRoleLister { + fake.clusterRoleListerMutex.Lock() + ret, specificReturn := fake.clusterRoleListerReturnsOnCall[len(fake.clusterRoleListerArgsForCall)] + fake.clusterRoleListerArgsForCall = append(fake.clusterRoleListerArgsForCall, struct { + }{}) + fake.recordInvocation("ClusterRoleLister", []interface{}{}) + fake.clusterRoleListerMutex.Unlock() + if fake.ClusterRoleListerStub != nil { + return fake.ClusterRoleListerStub() + } + if specificReturn { + return ret.result1 + } + fakeReturns := fake.clusterRoleListerReturns + return fakeReturns.result1 +} + +func (fake *FakeRbacV1Lister) ClusterRoleListerCallCount() int { + fake.clusterRoleListerMutex.RLock() + defer fake.clusterRoleListerMutex.RUnlock() + return len(fake.clusterRoleListerArgsForCall) +} + +func (fake *FakeRbacV1Lister) ClusterRoleListerCalls(stub func() v1.ClusterRoleLister) { + fake.clusterRoleListerMutex.Lock() + defer fake.clusterRoleListerMutex.Unlock() + fake.ClusterRoleListerStub = stub +} + +func (fake *FakeRbacV1Lister) ClusterRoleListerReturns(result1 v1.ClusterRoleLister) { + fake.clusterRoleListerMutex.Lock() + defer fake.clusterRoleListerMutex.Unlock() + fake.ClusterRoleListerStub = nil + fake.clusterRoleListerReturns = struct { + result1 v1.ClusterRoleLister + }{result1} +} + +func (fake *FakeRbacV1Lister) ClusterRoleListerReturnsOnCall(i int, result1 v1.ClusterRoleLister) { + fake.clusterRoleListerMutex.Lock() + defer fake.clusterRoleListerMutex.Unlock() + fake.ClusterRoleListerStub = nil + if fake.clusterRoleListerReturnsOnCall == nil { + fake.clusterRoleListerReturnsOnCall = make(map[int]struct { + result1 v1.ClusterRoleLister + }) + } + fake.clusterRoleListerReturnsOnCall[i] = struct { + result1 v1.ClusterRoleLister + }{result1} +} + +func (fake *FakeRbacV1Lister) RegisterClusterRoleBindingLister(arg1 v1.ClusterRoleBindingLister) { + fake.registerClusterRoleBindingListerMutex.Lock() + fake.registerClusterRoleBindingListerArgsForCall = append(fake.registerClusterRoleBindingListerArgsForCall, struct { + arg1 v1.ClusterRoleBindingLister + }{arg1}) + fake.recordInvocation("RegisterClusterRoleBindingLister", []interface{}{arg1}) + fake.registerClusterRoleBindingListerMutex.Unlock() + if fake.RegisterClusterRoleBindingListerStub != nil { + fake.RegisterClusterRoleBindingListerStub(arg1) + } +} + +func (fake *FakeRbacV1Lister) RegisterClusterRoleBindingListerCallCount() int { + fake.registerClusterRoleBindingListerMutex.RLock() + defer fake.registerClusterRoleBindingListerMutex.RUnlock() + return len(fake.registerClusterRoleBindingListerArgsForCall) +} + +func (fake *FakeRbacV1Lister) RegisterClusterRoleBindingListerCalls(stub func(v1.ClusterRoleBindingLister)) { + fake.registerClusterRoleBindingListerMutex.Lock() + defer fake.registerClusterRoleBindingListerMutex.Unlock() + fake.RegisterClusterRoleBindingListerStub = stub +} + +func (fake *FakeRbacV1Lister) RegisterClusterRoleBindingListerArgsForCall(i int) v1.ClusterRoleBindingLister { + fake.registerClusterRoleBindingListerMutex.RLock() + defer fake.registerClusterRoleBindingListerMutex.RUnlock() + argsForCall := fake.registerClusterRoleBindingListerArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FakeRbacV1Lister) RegisterClusterRoleLister(arg1 v1.ClusterRoleLister) { + fake.registerClusterRoleListerMutex.Lock() + fake.registerClusterRoleListerArgsForCall = append(fake.registerClusterRoleListerArgsForCall, struct { + arg1 v1.ClusterRoleLister + }{arg1}) + fake.recordInvocation("RegisterClusterRoleLister", []interface{}{arg1}) + fake.registerClusterRoleListerMutex.Unlock() + if fake.RegisterClusterRoleListerStub != nil { + fake.RegisterClusterRoleListerStub(arg1) + } +} + +func (fake *FakeRbacV1Lister) RegisterClusterRoleListerCallCount() int { + fake.registerClusterRoleListerMutex.RLock() + defer fake.registerClusterRoleListerMutex.RUnlock() + return len(fake.registerClusterRoleListerArgsForCall) +} + +func (fake *FakeRbacV1Lister) RegisterClusterRoleListerCalls(stub func(v1.ClusterRoleLister)) { + fake.registerClusterRoleListerMutex.Lock() + defer fake.registerClusterRoleListerMutex.Unlock() + fake.RegisterClusterRoleListerStub = stub +} + +func (fake *FakeRbacV1Lister) RegisterClusterRoleListerArgsForCall(i int) v1.ClusterRoleLister { + fake.registerClusterRoleListerMutex.RLock() + defer fake.registerClusterRoleListerMutex.RUnlock() + argsForCall := fake.registerClusterRoleListerArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FakeRbacV1Lister) RegisterRoleBindingLister(arg1 string, arg2 v1.RoleBindingLister) { + fake.registerRoleBindingListerMutex.Lock() + fake.registerRoleBindingListerArgsForCall = append(fake.registerRoleBindingListerArgsForCall, struct { + arg1 string + arg2 v1.RoleBindingLister + }{arg1, arg2}) + fake.recordInvocation("RegisterRoleBindingLister", []interface{}{arg1, arg2}) + fake.registerRoleBindingListerMutex.Unlock() + if fake.RegisterRoleBindingListerStub != nil { + fake.RegisterRoleBindingListerStub(arg1, arg2) + } +} + +func (fake *FakeRbacV1Lister) RegisterRoleBindingListerCallCount() int { + fake.registerRoleBindingListerMutex.RLock() + defer fake.registerRoleBindingListerMutex.RUnlock() + return len(fake.registerRoleBindingListerArgsForCall) +} + +func (fake *FakeRbacV1Lister) RegisterRoleBindingListerCalls(stub func(string, v1.RoleBindingLister)) { + fake.registerRoleBindingListerMutex.Lock() + defer fake.registerRoleBindingListerMutex.Unlock() + fake.RegisterRoleBindingListerStub = stub +} + +func (fake *FakeRbacV1Lister) RegisterRoleBindingListerArgsForCall(i int) (string, v1.RoleBindingLister) { + fake.registerRoleBindingListerMutex.RLock() + defer fake.registerRoleBindingListerMutex.RUnlock() + argsForCall := fake.registerRoleBindingListerArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2 +} + +func (fake *FakeRbacV1Lister) RegisterRoleLister(arg1 string, arg2 v1.RoleLister) { + fake.registerRoleListerMutex.Lock() + fake.registerRoleListerArgsForCall = append(fake.registerRoleListerArgsForCall, struct { + arg1 string + arg2 v1.RoleLister + }{arg1, arg2}) + fake.recordInvocation("RegisterRoleLister", []interface{}{arg1, arg2}) + fake.registerRoleListerMutex.Unlock() + if fake.RegisterRoleListerStub != nil { + fake.RegisterRoleListerStub(arg1, arg2) + } +} + +func (fake *FakeRbacV1Lister) RegisterRoleListerCallCount() int { + fake.registerRoleListerMutex.RLock() + defer fake.registerRoleListerMutex.RUnlock() + return len(fake.registerRoleListerArgsForCall) +} + +func (fake *FakeRbacV1Lister) RegisterRoleListerCalls(stub func(string, v1.RoleLister)) { + fake.registerRoleListerMutex.Lock() + defer fake.registerRoleListerMutex.Unlock() + fake.RegisterRoleListerStub = stub +} + +func (fake *FakeRbacV1Lister) RegisterRoleListerArgsForCall(i int) (string, v1.RoleLister) { + fake.registerRoleListerMutex.RLock() + defer fake.registerRoleListerMutex.RUnlock() + argsForCall := fake.registerRoleListerArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2 +} + +func (fake *FakeRbacV1Lister) RoleBindingLister() v1.RoleBindingLister { + fake.roleBindingListerMutex.Lock() + ret, specificReturn := fake.roleBindingListerReturnsOnCall[len(fake.roleBindingListerArgsForCall)] + fake.roleBindingListerArgsForCall = append(fake.roleBindingListerArgsForCall, struct { + }{}) + fake.recordInvocation("RoleBindingLister", []interface{}{}) + fake.roleBindingListerMutex.Unlock() + if fake.RoleBindingListerStub != nil { + return fake.RoleBindingListerStub() + } + if specificReturn { + return ret.result1 + } + fakeReturns := fake.roleBindingListerReturns + return fakeReturns.result1 +} + +func (fake *FakeRbacV1Lister) RoleBindingListerCallCount() int { + fake.roleBindingListerMutex.RLock() + defer fake.roleBindingListerMutex.RUnlock() + return len(fake.roleBindingListerArgsForCall) +} + +func (fake *FakeRbacV1Lister) RoleBindingListerCalls(stub func() v1.RoleBindingLister) { + fake.roleBindingListerMutex.Lock() + defer fake.roleBindingListerMutex.Unlock() + fake.RoleBindingListerStub = stub +} + +func (fake *FakeRbacV1Lister) RoleBindingListerReturns(result1 v1.RoleBindingLister) { + fake.roleBindingListerMutex.Lock() + defer fake.roleBindingListerMutex.Unlock() + fake.RoleBindingListerStub = nil + fake.roleBindingListerReturns = struct { + result1 v1.RoleBindingLister + }{result1} +} + +func (fake *FakeRbacV1Lister) RoleBindingListerReturnsOnCall(i int, result1 v1.RoleBindingLister) { + fake.roleBindingListerMutex.Lock() + defer fake.roleBindingListerMutex.Unlock() + fake.RoleBindingListerStub = nil + if fake.roleBindingListerReturnsOnCall == nil { + fake.roleBindingListerReturnsOnCall = make(map[int]struct { + result1 v1.RoleBindingLister + }) + } + fake.roleBindingListerReturnsOnCall[i] = struct { + result1 v1.RoleBindingLister + }{result1} +} + +func (fake *FakeRbacV1Lister) RoleLister() v1.RoleLister { + fake.roleListerMutex.Lock() + ret, specificReturn := fake.roleListerReturnsOnCall[len(fake.roleListerArgsForCall)] + fake.roleListerArgsForCall = append(fake.roleListerArgsForCall, struct { + }{}) + fake.recordInvocation("RoleLister", []interface{}{}) + fake.roleListerMutex.Unlock() + if fake.RoleListerStub != nil { + return fake.RoleListerStub() + } + if specificReturn { + return ret.result1 + } + fakeReturns := fake.roleListerReturns + return fakeReturns.result1 +} + +func (fake *FakeRbacV1Lister) RoleListerCallCount() int { + fake.roleListerMutex.RLock() + defer fake.roleListerMutex.RUnlock() + return len(fake.roleListerArgsForCall) +} + +func (fake *FakeRbacV1Lister) RoleListerCalls(stub func() v1.RoleLister) { + fake.roleListerMutex.Lock() + defer fake.roleListerMutex.Unlock() + fake.RoleListerStub = stub +} + +func (fake *FakeRbacV1Lister) RoleListerReturns(result1 v1.RoleLister) { + fake.roleListerMutex.Lock() + defer fake.roleListerMutex.Unlock() + fake.RoleListerStub = nil + fake.roleListerReturns = struct { + result1 v1.RoleLister + }{result1} +} + +func (fake *FakeRbacV1Lister) RoleListerReturnsOnCall(i int, result1 v1.RoleLister) { + fake.roleListerMutex.Lock() + defer fake.roleListerMutex.Unlock() + fake.RoleListerStub = nil + if fake.roleListerReturnsOnCall == nil { + fake.roleListerReturnsOnCall = make(map[int]struct { + result1 v1.RoleLister + }) + } + fake.roleListerReturnsOnCall[i] = struct { + result1 v1.RoleLister + }{result1} +} + +func (fake *FakeRbacV1Lister) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.clusterRoleBindingListerMutex.RLock() + defer fake.clusterRoleBindingListerMutex.RUnlock() + fake.clusterRoleListerMutex.RLock() + defer fake.clusterRoleListerMutex.RUnlock() + fake.registerClusterRoleBindingListerMutex.RLock() + defer fake.registerClusterRoleBindingListerMutex.RUnlock() + fake.registerClusterRoleListerMutex.RLock() + defer fake.registerClusterRoleListerMutex.RUnlock() + fake.registerRoleBindingListerMutex.RLock() + defer fake.registerRoleBindingListerMutex.RUnlock() + fake.registerRoleListerMutex.RLock() + defer fake.registerRoleListerMutex.RUnlock() + fake.roleBindingListerMutex.RLock() + defer fake.roleBindingListerMutex.RUnlock() + fake.roleListerMutex.RLock() + defer fake.roleListerMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *FakeRbacV1Lister) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} + +var _ operatorlister.RbacV1Lister = new(FakeRbacV1Lister) diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/pod.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/pod.go new file mode 100644 index 0000000000..1dcaf0bc11 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/pod.go @@ -0,0 +1,94 @@ +package operatorlister + +import ( + "fmt" + "sync" + + "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/types" + corev1 "k8s.io/client-go/listers/core/v1" +) + +type UnionPodLister struct { + podListers map[string]corev1.PodLister + podLock sync.RWMutex +} + +// List lists all Pods in the indexer. +func (usl *UnionPodLister) List(selector labels.Selector) (ret []*v1.Pod, err error) { + usl.podLock.RLock() + defer usl.podLock.RUnlock() + + set := make(map[types.UID]*v1.Pod) + for _, sl := range usl.podListers { + pods, err := sl.List(selector) + if err != nil { + return nil, err + } + + for _, pod := range pods { + set[pod.GetUID()] = pod + } + } + + for _, pod := range set { + ret = append(ret, pod) + } + + return +} + +// Pods returns an object that can list and get Pods. +func (usl *UnionPodLister) Pods(namespace string) corev1.PodNamespaceLister { + usl.podLock.RLock() + defer usl.podLock.RUnlock() + + // Check for specific namespace listers + if sl, ok := usl.podListers[namespace]; ok { + return sl.Pods(namespace) + } + + // Check for any namespace-all listers + if sl, ok := usl.podListers[metav1.NamespaceAll]; ok { + return sl.Pods(namespace) + } + + return &NullPodNamespaceLister{} +} + +func (usl *UnionPodLister) RegisterPodLister(namespace string, lister corev1.PodLister) { + usl.podLock.Lock() + defer usl.podLock.Unlock() + + if usl.podListers == nil { + usl.podListers = make(map[string]corev1.PodLister) + } + usl.podListers[namespace] = lister +} + +func (l *coreV1Lister) RegisterPodLister(namespace string, lister corev1.PodLister) { + l.podLister.RegisterPodLister(namespace, lister) +} + +func (l *coreV1Lister) PodLister() corev1.PodLister { + return l.podLister +} + +// NullPodNamespaceLister is an implementation of a null PodNamespaceLister. It is +// used to prevent nil pointers when no PodNamespaceLister has been registered for a given +// namespace. +type NullPodNamespaceLister struct { + corev1.PodNamespaceLister +} + +// List returns nil and an error explaining that this is a NullPodNamespaceLister. +func (n *NullPodNamespaceLister) List(selector labels.Selector) (ret []*v1.Pod, err error) { + return nil, fmt.Errorf("cannot list Pods with a NullPodNamespaceLister") +} + +// Get returns nil and an error explaining that this is a NullPodNamespaceLister. +func (n *NullPodNamespaceLister) Get(name string) (*v1.Pod, error) { + return nil, fmt.Errorf("cannot get Pod with a NullPodNamespaceLister") +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/role.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/role.go new file mode 100644 index 0000000000..0bf360ec90 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/role.go @@ -0,0 +1,94 @@ +package operatorlister + +import ( + "fmt" + "sync" + + v1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/types" + rbacv1 "k8s.io/client-go/listers/rbac/v1" +) + +type UnionRoleLister struct { + roleListers map[string]rbacv1.RoleLister + roleLock sync.RWMutex +} + +// List lists all Roles in the indexer. +func (rl *UnionRoleLister) List(selector labels.Selector) (ret []*v1.Role, err error) { + rl.roleLock.RLock() + defer rl.roleLock.RUnlock() + + set := make(map[types.UID]*v1.Role) + for _, dl := range rl.roleListers { + roles, err := dl.List(selector) + if err != nil { + return nil, err + } + + for _, role := range roles { + set[role.GetUID()] = role + } + } + + for _, role := range set { + ret = append(ret, role) + } + + return +} + +// Roles returns an object that can list and get Roles. +func (rl *UnionRoleLister) Roles(namespace string) rbacv1.RoleNamespaceLister { + rl.roleLock.RLock() + defer rl.roleLock.RUnlock() + + // Check for specific namespace listers + if dl, ok := rl.roleListers[namespace]; ok { + return dl.Roles(namespace) + } + + // Check for any namespace-all listers + if dl, ok := rl.roleListers[metav1.NamespaceAll]; ok { + return dl.Roles(namespace) + } + + return &NullRoleNamespaceLister{} +} + +func (rl *UnionRoleLister) RegisterRoleLister(namespace string, lister rbacv1.RoleLister) { + rl.roleLock.Lock() + defer rl.roleLock.Unlock() + + if rl.roleListers == nil { + rl.roleListers = make(map[string]rbacv1.RoleLister) + } + rl.roleListers[namespace] = lister +} + +func (l *rbacV1Lister) RegisterRoleLister(namespace string, lister rbacv1.RoleLister) { + l.roleLister.RegisterRoleLister(namespace, lister) +} + +func (l *rbacV1Lister) RoleLister() rbacv1.RoleLister { + return l.roleLister +} + +// NullRoleNamespaceLister is an implementation of a null RoleNamespaceLister. It is +// used to prevent nil pointers when no RoleNamespaceLister has been registered for a given +// namespace. +type NullRoleNamespaceLister struct { + rbacv1.RoleNamespaceLister +} + +// List returns nil and an error explaining that this is a NullRoleNamespaceLister. +func (n *NullRoleNamespaceLister) List(selector labels.Selector) (ret []*v1.Role, err error) { + return nil, fmt.Errorf("cannot list Roles with a NullRoleNamespaceLister") +} + +// Get returns nil and an error explaining that this is a NullRoleNamespaceLister. +func (n *NullRoleNamespaceLister) Get(name string) (*v1.Role, error) { + return nil, fmt.Errorf("cannot get Role with a NullRoleNamespaceLister") +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/rolebinding.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/rolebinding.go new file mode 100644 index 0000000000..2227a1616d --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/rolebinding.go @@ -0,0 +1,94 @@ +package operatorlister + +import ( + "fmt" + "sync" + + v1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/types" + rbacv1 "k8s.io/client-go/listers/rbac/v1" +) + +type UnionRoleBindingLister struct { + roleBindingListers map[string]rbacv1.RoleBindingLister + roleBindingLock sync.RWMutex +} + +// List lists all RoleBindings in the indexer. +func (rbl *UnionRoleBindingLister) List(selector labels.Selector) (ret []*v1.RoleBinding, err error) { + rbl.roleBindingLock.RLock() + defer rbl.roleBindingLock.RUnlock() + + set := make(map[types.UID]*v1.RoleBinding) + for _, dl := range rbl.roleBindingListers { + roleBindings, err := dl.List(selector) + if err != nil { + return nil, err + } + + for _, roleBinding := range roleBindings { + set[roleBinding.GetUID()] = roleBinding + } + } + + for _, roleBinding := range set { + ret = append(ret, roleBinding) + } + + return +} + +// RoleBindings returns an object that can list and get RoleBindings. +func (rbl *UnionRoleBindingLister) RoleBindings(namespace string) rbacv1.RoleBindingNamespaceLister { + rbl.roleBindingLock.RLock() + defer rbl.roleBindingLock.RUnlock() + + // Check for specific namespace listers + if dl, ok := rbl.roleBindingListers[namespace]; ok { + return dl.RoleBindings(namespace) + } + + // Check for any namespace-all listers + if dl, ok := rbl.roleBindingListers[metav1.NamespaceAll]; ok { + return dl.RoleBindings(namespace) + } + + return &NullRoleBindingNamespaceLister{} +} + +func (rbl *UnionRoleBindingLister) RegisterRoleBindingLister(namespace string, lister rbacv1.RoleBindingLister) { + rbl.roleBindingLock.Lock() + defer rbl.roleBindingLock.Unlock() + + if rbl.roleBindingListers == nil { + rbl.roleBindingListers = make(map[string]rbacv1.RoleBindingLister) + } + rbl.roleBindingListers[namespace] = lister +} + +func (l *rbacV1Lister) RegisterRoleBindingLister(namespace string, lister rbacv1.RoleBindingLister) { + l.roleBindingLister.RegisterRoleBindingLister(namespace, lister) +} + +func (l *rbacV1Lister) RoleBindingLister() rbacv1.RoleBindingLister { + return l.roleBindingLister +} + +// NullRoleBindingNamespaceLister is an implementation of a null RoleBindingNamespaceLister. It is +// used to prevent nil pointers when no RoleBindingNamespaceLister has been registered for a given +// namespace. +type NullRoleBindingNamespaceLister struct { + rbacv1.RoleBindingNamespaceLister +} + +// List returns nil and an error explaining that this is a NullRoleBindingNamespaceLister. +func (n *NullRoleBindingNamespaceLister) List(selector labels.Selector) (ret []*v1.RoleBinding, err error) { + return nil, fmt.Errorf("cannot list RoleBindings with a NullRoleBindingNamespaceLister") +} + +// Get returns nil and an error explaining that this is a NullRoleBindingNamespaceLister. +func (n *NullRoleBindingNamespaceLister) Get(name string) (*v1.RoleBinding, error) { + return nil, fmt.Errorf("cannot get RoleBinding with a NullRoleBindingNamespaceLister") +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/secret.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/secret.go new file mode 100644 index 0000000000..b059c7bfc1 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/secret.go @@ -0,0 +1,94 @@ +package operatorlister + +import ( + "fmt" + "sync" + + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/types" + corev1 "k8s.io/client-go/listers/core/v1" +) + +type UnionSecretLister struct { + secretListers map[string]corev1.SecretLister + secretLock sync.RWMutex +} + +// List lists all Secrets in the indexer. +func (usl *UnionSecretLister) List(selector labels.Selector) (ret []*v1.Secret, err error) { + usl.secretLock.RLock() + defer usl.secretLock.RUnlock() + + set := make(map[types.UID]*v1.Secret) + for _, sl := range usl.secretListers { + secrets, err := sl.List(selector) + if err != nil { + return nil, err + } + + for _, secret := range secrets { + set[secret.GetUID()] = secret + } + } + + for _, secret := range set { + ret = append(ret, secret) + } + + return +} + +// Secrets returns an object that can list and get Secrets. +func (usl *UnionSecretLister) Secrets(namespace string) corev1.SecretNamespaceLister { + usl.secretLock.RLock() + defer usl.secretLock.RUnlock() + + // Check for specific namespace listers + if sl, ok := usl.secretListers[namespace]; ok { + return sl.Secrets(namespace) + } + + // Check for any namespace-all listers + if sl, ok := usl.secretListers[metav1.NamespaceAll]; ok { + return sl.Secrets(namespace) + } + + return &NullSecretNamespaceLister{} +} + +func (usl *UnionSecretLister) RegisterSecretLister(namespace string, lister corev1.SecretLister) { + usl.secretLock.Lock() + defer usl.secretLock.Unlock() + + if usl.secretListers == nil { + usl.secretListers = make(map[string]corev1.SecretLister) + } + usl.secretListers[namespace] = lister +} + +func (l *coreV1Lister) RegisterSecretLister(namespace string, lister corev1.SecretLister) { + l.secretLister.RegisterSecretLister(namespace, lister) +} + +func (l *coreV1Lister) SecretLister() corev1.SecretLister { + return l.secretLister +} + +// NullSecretNamespaceLister is an implementation of a null SecretNamespaceLister. It is +// used to prevent nil pointers when no SecretNamespaceLister has been registered for a given +// namespace. +type NullSecretNamespaceLister struct { + corev1.SecretNamespaceLister +} + +// List returns nil and an error explaining that this is a NullSecretNamespaceLister. +func (n *NullSecretNamespaceLister) List(selector labels.Selector) (ret []*v1.Secret, err error) { + return nil, fmt.Errorf("cannot list Secrets with a NullSecretNamespaceLister") +} + +// Get returns nil and an error explaining that this is a NullSecretNamespaceLister. +func (n *NullSecretNamespaceLister) Get(name string) (*v1.Secret, error) { + return nil, fmt.Errorf("cannot get Secret with a NullSecretNamespaceLister") +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/service.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/service.go new file mode 100644 index 0000000000..0bbb59c899 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/service.go @@ -0,0 +1,116 @@ +package operatorlister + +import ( + "fmt" + "sync" + + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/types" + corev1 "k8s.io/client-go/listers/core/v1" +) + +type UnionServiceLister struct { + serviceListers map[string]corev1.ServiceLister + serviceLock sync.RWMutex +} + +// List lists all Services in the indexer. +func (usl *UnionServiceLister) List(selector labels.Selector) (ret []*v1.Service, err error) { + usl.serviceLock.RLock() + defer usl.serviceLock.RUnlock() + + set := make(map[types.UID]*v1.Service) + for _, sl := range usl.serviceListers { + services, err := sl.List(selector) + if err != nil { + return nil, err + } + + for _, service := range services { + set[service.GetUID()] = service + } + } + + for _, service := range set { + ret = append(ret, service) + } + + return +} + +// Services returns an object that can list and get Services. +func (usl *UnionServiceLister) Services(namespace string) corev1.ServiceNamespaceLister { + usl.serviceLock.RLock() + defer usl.serviceLock.RUnlock() + + // Check for specific namespace listers + if sl, ok := usl.serviceListers[namespace]; ok { + return sl.Services(namespace) + } + + // Check for any namespace-all listers + if sl, ok := usl.serviceListers[metav1.NamespaceAll]; ok { + return sl.Services(namespace) + } + + return &NullServiceNamespaceLister{} +} + +func (usl *UnionServiceLister) GetPodServices(pod *v1.Pod) ([]*v1.Service, error) { + usl.serviceLock.RLock() + defer usl.serviceLock.RUnlock() + + // Check for specific namespace listers + if sl, ok := usl.serviceListers[pod.GetNamespace()]; ok { + return sl.GetPodServices(pod) + } + + // Check for any namespace-all listers + if sl, ok := usl.serviceListers[metav1.NamespaceAll]; ok { + return sl.GetPodServices(pod) + } + + return nil, fmt.Errorf("could not find service lister registered for namspace %s", pod.GetNamespace()) +} + +func (usl *UnionServiceLister) RegisterServiceLister(namespace string, lister corev1.ServiceLister) { + usl.serviceLock.Lock() + defer usl.serviceLock.Unlock() + + if usl.serviceListers == nil { + usl.serviceListers = make(map[string]corev1.ServiceLister) + } + usl.serviceListers[namespace] = lister +} + +func (l *coreV1Lister) RegisterServiceLister(namespace string, lister corev1.ServiceLister) { + l.serviceLister.RegisterServiceLister(namespace, lister) +} + +func (l *coreV1Lister) ServiceLister() corev1.ServiceLister { + return l.serviceLister +} + +// NullServiceNamespaceLister is an implementation of a null ServiceNamespaceLister. It is +// used to prevent nil pointers when no ServiceNamespaceLister has been registered for a given +// namespace. +type NullServiceNamespaceLister struct { + corev1.ServiceNamespaceLister +} + +// List returns nil and an error explaining that this is a NullServiceNamespaceLister. +func (n *NullServiceNamespaceLister) List(selector labels.Selector) (ret []*v1.Service, err error) { + return nil, fmt.Errorf("cannot list Services with a NullServiceNamespaceLister") +} + +// Get returns nil and an error explaining that this is a NullServiceNamespaceLister. +func (n *NullServiceNamespaceLister) Get(name string) (*v1.Service, error) { + return nil, fmt.Errorf("cannot get Service with a NullServiceNamespaceLister") +} + +// GetPodServices returns nil and an error explaining that this is a NullServiceNamespaceLister. +func (n *NullServiceNamespaceLister) GetPodServices(pod *v1.Pod) ([]*v1.Service, error) { + return nil, fmt.Errorf("could not get pod services with a NullServiceNamespaceLister") +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/serviceaccount.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/serviceaccount.go new file mode 100644 index 0000000000..3ff3cf0b86 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/serviceaccount.go @@ -0,0 +1,94 @@ +package operatorlister + +import ( + "fmt" + "sync" + + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/types" + corev1 "k8s.io/client-go/listers/core/v1" +) + +type UnionServiceAccountLister struct { + serviceAccountListers map[string]corev1.ServiceAccountLister + serviceAccountLock sync.RWMutex +} + +// List lists all ServiceAccounts in the indexer. +func (usl *UnionServiceAccountLister) List(selector labels.Selector) (ret []*v1.ServiceAccount, err error) { + usl.serviceAccountLock.RLock() + defer usl.serviceAccountLock.RUnlock() + + set := make(map[types.UID]*v1.ServiceAccount) + for _, sl := range usl.serviceAccountListers { + serviceAccounts, err := sl.List(selector) + if err != nil { + return nil, err + } + + for _, serviceAccount := range serviceAccounts { + set[serviceAccount.GetUID()] = serviceAccount + } + } + + for _, serviceAccount := range set { + ret = append(ret, serviceAccount) + } + + return +} + +// ServiceAccounts returns an object that can list and get ServiceAccounts. +func (usl *UnionServiceAccountLister) ServiceAccounts(namespace string) corev1.ServiceAccountNamespaceLister { + usl.serviceAccountLock.RLock() + defer usl.serviceAccountLock.RUnlock() + + // Check for specific namespace listers + if sl, ok := usl.serviceAccountListers[namespace]; ok { + return sl.ServiceAccounts(namespace) + } + + // Check for any namespace-all listers + if sl, ok := usl.serviceAccountListers[metav1.NamespaceAll]; ok { + return sl.ServiceAccounts(namespace) + } + + return &NullServiceAccountNamespaceLister{} +} + +func (usl *UnionServiceAccountLister) RegisterServiceAccountLister(namespace string, lister corev1.ServiceAccountLister) { + usl.serviceAccountLock.Lock() + defer usl.serviceAccountLock.Unlock() + + if usl.serviceAccountListers == nil { + usl.serviceAccountListers = make(map[string]corev1.ServiceAccountLister) + } + usl.serviceAccountListers[namespace] = lister +} + +func (l *coreV1Lister) RegisterServiceAccountLister(namespace string, lister corev1.ServiceAccountLister) { + l.serviceAccountLister.RegisterServiceAccountLister(namespace, lister) +} + +func (l *coreV1Lister) ServiceAccountLister() corev1.ServiceAccountLister { + return l.serviceAccountLister +} + +// NullServiceAccountNamespaceLister is an implementation of a null ServiceAccountNamespaceLister. It is +// used to prevent nil pointers when no ServiceAccountNamespaceLister has been registered for a given +// namespace. +type NullServiceAccountNamespaceLister struct { + corev1.ServiceAccountNamespaceLister +} + +// List returns nil and an error explaining that this is a NullServiceAccountNamespaceLister. +func (n *NullServiceAccountNamespaceLister) List(selector labels.Selector) (ret []*v1.ServiceAccount, err error) { + return nil, fmt.Errorf("cannot list ServiceAccounts with a NullServiceAccountNamespaceLister") +} + +// Get returns nil and an error explaining that this is a NullServiceAccountNamespaceLister. +func (n *NullServiceAccountNamespaceLister) Get(name string) (*v1.ServiceAccount, error) { + return nil, fmt.Errorf("cannot get ServiceAccount with a NullServiceAccountNamespaceLister") +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/subscription.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/subscription.go new file mode 100644 index 0000000000..5e3a1a0387 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/subscription.go @@ -0,0 +1,96 @@ +package operatorlister + +import ( + "fmt" + "sync" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/types" + + "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + listers "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1alpha1" +) + +type UnionSubscriptionLister struct { + subscriptionListers map[string]listers.SubscriptionLister + subscriptionLock sync.RWMutex +} + +// List lists all Subscriptions in the indexer. +func (usl *UnionSubscriptionLister) List(selector labels.Selector) (ret []*v1alpha1.Subscription, err error) { + usl.subscriptionLock.RLock() + defer usl.subscriptionLock.RUnlock() + + set := make(map[types.UID]*v1alpha1.Subscription) + for _, cl := range usl.subscriptionListers { + subscriptions, err := cl.List(selector) + if err != nil { + return nil, err + } + + for _, subscription := range subscriptions { + set[subscription.GetUID()] = subscription + } + } + + for _, subscription := range set { + ret = append(ret, subscription) + } + + return +} + +// Subscriptions returns an object that can list and get Subscriptions. +func (usl *UnionSubscriptionLister) Subscriptions(namespace string) listers.SubscriptionNamespaceLister { + usl.subscriptionLock.RLock() + defer usl.subscriptionLock.RUnlock() + + // Check for specific namespace listers + if cl, ok := usl.subscriptionListers[namespace]; ok { + return cl.Subscriptions(namespace) + } + + // Check for any namespace-all listers + if cl, ok := usl.subscriptionListers[metav1.NamespaceAll]; ok { + return cl.Subscriptions(namespace) + } + + return &NullSubscriptionNamespaceLister{} +} + +func (usl *UnionSubscriptionLister) RegisterSubscriptionLister(namespace string, lister listers.SubscriptionLister) { + usl.subscriptionLock.Lock() + defer usl.subscriptionLock.Unlock() + + if usl.subscriptionListers == nil { + usl.subscriptionListers = make(map[string]listers.SubscriptionLister) + } + + usl.subscriptionListers[namespace] = lister +} + +func (l *operatorsV1alpha1Lister) RegisterSubscriptionLister(namespace string, lister listers.SubscriptionLister) { + l.subscriptionLister.RegisterSubscriptionLister(namespace, lister) +} + +func (l *operatorsV1alpha1Lister) SubscriptionLister() listers.SubscriptionLister { + return l.subscriptionLister +} + +// NullSubscriptionNamespaceLister is an implementation of a null SubscriptionNamespaceLister. It is +// used to prevent nil pointers when no SubscriptionNamespaceLister has been registered for a given +// namespace. +type NullSubscriptionNamespaceLister struct { + listers.SubscriptionNamespaceLister +} + +// List returns nil and an error explaining that this is a NullSubscriptionNamespaceLister. +func (n *NullSubscriptionNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.Subscription, err error) { + return nil, fmt.Errorf("cannot list Subscriptions with a NullSubscriptionNamespaceLister") +} + +// Get returns nil and an error explaining that this is a NullSubscriptionNamespaceLister. +func (n *NullSubscriptionNamespaceLister) Get(name string) (*v1alpha1.Subscription, error) { + return nil, fmt.Errorf("cannot get Subscription with a NullSubscriptionNamespaceLister") +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorstatus/status.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorstatus/status.go new file mode 100644 index 0000000000..2f4a9f1b10 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorstatus/status.go @@ -0,0 +1,206 @@ +package operatorstatus + +import ( + "fmt" + "os" + "reflect" + "time" + + configv1 "github.com/openshift/api/config/v1" + configv1client "github.com/openshift/client-go/config/clientset/versioned/typed/config/v1" + log "github.com/sirupsen/logrus" + k8serrors "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/wait" + "k8s.io/client-go/discovery" + + "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient" + olmversion "github.com/operator-framework/operator-lifecycle-manager/pkg/version" +) + +func MonitorClusterStatus(name string, syncCh chan error, stopCh <-chan struct{}, opClient operatorclient.ClientInterface, configClient configv1client.ConfigV1Interface) { + var ( + syncs int + successfulSyncs int + hasClusterOperator bool + ) + go wait.Until(func() { + // slow poll until we see a cluster operator API, which could be never + if !hasClusterOperator { + opStatusGV := schema.GroupVersion{ + Group: "config.openshift.io", + Version: "v1", + } + err := discovery.ServerSupportsVersion(opClient.KubernetesInterface().Discovery(), opStatusGV) + if err != nil { + log.Infof("ClusterOperator api not present, skipping update (%v)", err) + time.Sleep(time.Minute) + return + } + hasClusterOperator = true + } + + // Sample the sync channel and see whether we're successfully retiring syncs as a + // proxy for "working" (we can't know when we hit level, but we can at least verify + // we are seeing some syncs succeeding). Once we observe at least one successful + // sync we can begin reporting available and level. + select { + case err, ok := <-syncCh: + if !ok { + // syncCh should only close if the Run() loop exits + time.Sleep(5 * time.Second) + log.Fatalf("Status sync channel closed but process did not exit in time") + } + syncs++ + if err == nil { + successfulSyncs++ + } + // grab any other sync events that have accumulated + for len(syncCh) > 0 { + if err := <-syncCh; err == nil { + successfulSyncs++ + } + syncs++ + } + // if we haven't yet accumulated enough syncs, wait longer + // TODO: replace these magic numbers with a better measure of syncs across all queueInformers + if successfulSyncs < 5 || syncs < 10 { + log.Printf("Waiting to observe more successful syncs") + return + } + } + + // create the cluster operator in an initial state if it does not exist + existing, err := configClient.ClusterOperators().Get(name, metav1.GetOptions{}) + if k8serrors.IsNotFound(err) { + log.Info("Existing operator status not found, creating") + created, createErr := configClient.ClusterOperators().Create(&configv1.ClusterOperator{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + Status: configv1.ClusterOperatorStatus{ + Conditions: []configv1.ClusterOperatorStatusCondition{ + { + Type: configv1.OperatorProgressing, + Status: configv1.ConditionTrue, + Message: fmt.Sprintf("Installing %s", olmversion.OLMVersion), + LastTransitionTime: metav1.Now(), + }, + { + Type: configv1.OperatorFailing, + Status: configv1.ConditionFalse, + LastTransitionTime: metav1.Now(), + }, + { + Type: configv1.OperatorAvailable, + Status: configv1.ConditionFalse, + LastTransitionTime: metav1.Now(), + }, + }, + }, + }) + if createErr != nil { + log.Errorf("Failed to create cluster operator: %v\n", createErr) + return + } + existing = created + err = nil + } + if err != nil { + log.Errorf("Unable to retrieve cluster operator: %v", err) + return + } + + // update the status with the appropriate state + previousStatus := existing.Status.DeepCopy() + switch { + case successfulSyncs > 0: + setOperatorStatusCondition(&existing.Status.Conditions, configv1.ClusterOperatorStatusCondition{ + Type: configv1.OperatorFailing, + Status: configv1.ConditionFalse, + }) + setOperatorStatusCondition(&existing.Status.Conditions, configv1.ClusterOperatorStatusCondition{ + Type: configv1.OperatorProgressing, + Status: configv1.ConditionFalse, + Message: fmt.Sprintf("Deployed %s", olmversion.OLMVersion), + }) + setOperatorStatusCondition(&existing.Status.Conditions, configv1.ClusterOperatorStatusCondition{ + Type: configv1.OperatorAvailable, + Status: configv1.ConditionTrue, + }) + // we set the versions array when all the latest code is deployed and running - in this case, + // the sync method is responsible for guaranteeing that happens before it returns nil + if version := os.Getenv("RELEASE_VERSION"); len(version) > 0 { + existing.Status.Versions = []configv1.OperandVersion{ + { + Name: "operator", + Version: version, + }, + { + Name: "operator-lifecycle-manager", + Version: olmversion.OLMVersion, + }, + } + } else { + existing.Status.Versions = nil + } + default: + setOperatorStatusCondition(&existing.Status.Conditions, configv1.ClusterOperatorStatusCondition{ + Type: configv1.OperatorFailing, + Status: configv1.ConditionTrue, + Message: "Waiting for updates to take effect", + }) + setOperatorStatusCondition(&existing.Status.Conditions, configv1.ClusterOperatorStatusCondition{ + Type: configv1.OperatorProgressing, + Status: configv1.ConditionFalse, + Message: fmt.Sprintf("Waiting to see update %s succeed", olmversion.OLMVersion), + }) + // TODO: use % errors within a window to report available + } + + // update the status + if !reflect.DeepEqual(previousStatus, &existing.Status) { + if _, err := configClient.ClusterOperators().UpdateStatus(existing); err != nil { + log.Errorf("Unable to update cluster operator status: %v", err) + } + } + + // if we've reported success, we can sleep longer, otherwise we want to keep watching for + // successful + if successfulSyncs > 0 { + time.Sleep(5 * time.Minute) + } + + }, 5*time.Second, stopCh) +} + +func setOperatorStatusCondition(conditions *[]configv1.ClusterOperatorStatusCondition, newCondition configv1.ClusterOperatorStatusCondition) { + if conditions == nil { + conditions = &[]configv1.ClusterOperatorStatusCondition{} + } + existingCondition := findOperatorStatusCondition(*conditions, newCondition.Type) + if existingCondition == nil { + newCondition.LastTransitionTime = metav1.NewTime(time.Now()) + *conditions = append(*conditions, newCondition) + return + } + + if existingCondition.Status != newCondition.Status { + existingCondition.Status = newCondition.Status + existingCondition.LastTransitionTime = newCondition.LastTransitionTime + } + + existingCondition.Reason = newCondition.Reason + existingCondition.Message = newCondition.Message +} + +func findOperatorStatusCondition(conditions []configv1.ClusterOperatorStatusCondition, conditionType configv1.ClusterStatusConditionType) *configv1.ClusterOperatorStatusCondition { + for i := range conditions { + if conditions[i].Type == conditionType { + return &conditions[i] + } + } + + return nil +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil/util.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil/util.go index 63e403c2a5..0f8ee56102 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil/util.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil/util.go @@ -1,16 +1,35 @@ package ownerutil import ( + "fmt" + + "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1" "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + log "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + rbac "k8s.io/api/rbac/v1" 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 ( + OwnerKey = "olm.owner" + OwnerNamespaceKey = "olm.owner.namespace" + OwnerKind = "olm.owner.kind" +) + +var ( + NotController = false + DontBlockOwnerDeletion = false +) + // Owner is used to build an OwnerReference, and we need type and object metadata type Owner interface { metav1.Object - schema.ObjectKind + runtime.Object } func IsOwnedBy(object metav1.Object, owner Owner) bool { @@ -31,27 +50,216 @@ func IsOwnedByKind(object metav1.Object, ownerKind string) bool { return false } -func GetOwnerByKind(object metav1.Object, ownerKind string) metav1.OwnerReference { +func GetOwnerByKind(object metav1.Object, ownerKind string) *metav1.OwnerReference { + for _, oref := range object.GetOwnerReferences() { + if oref.Kind == ownerKind { + return &oref + } + } + return nil +} + +func GetOwnerByKindLabel(object metav1.Object, ownerKind string) (name, namespace string, ok bool) { + if !IsOwnedByKindLabel(object, ownerKind) { + return + } + if object.GetLabels() == nil { + return + } + + namespace, ok = object.GetLabels()[OwnerNamespaceKey] + if !ok { + return + } + ok = false + + name, ok = object.GetLabels()[OwnerKey] + return +} + +// GetOwnersByKind returns all OwnerReferences of the given kind listed by the given object +func GetOwnersByKind(object metav1.Object, ownerKind string) []metav1.OwnerReference { + var orefs []metav1.OwnerReference for _, oref := range object.GetOwnerReferences() { if oref.Kind == ownerKind { - return oref + orefs = append(orefs, oref) } } - return metav1.OwnerReference{} + return orefs +} + +// HasOwnerConflict checks if the given list of OwnerReferences points to owners other than the target. +// This function returns true if the list of OwnerReferences is empty or contains elements of the same kind as +// the target but does not include the target OwnerReference itself. This function returns false if the list contains +// the target, or has no elements of the same kind as the target. +// +// Note: This is imporant when determining if a Role, RoleBinding, ClusterRole, or ClusterRoleBinding +// can be used to satisfy permissions of a CSV. If the target CSV is not a member of the RBAC resource's +// OwnerReferences, then we know the resource can be garbage collected by OLM independently of the target +// CSV +func HasOwnerConflict(target Owner, owners []metav1.OwnerReference) bool { + // Infer TypeMeta for the target + if err := InferGroupVersionKind(target); err != nil { + log.Warn(err.Error()) + } + + conflicts := false + for _, owner := range owners { + gvk := target.GetObjectKind().GroupVersionKind() + if owner.Kind == gvk.Kind && owner.APIVersion == gvk.Version { + if owner.Name == target.GetName() && owner.UID == target.GetUID() { + return false + } + + conflicts = true + } + } + + return conflicts +} + +// Adoptable checks whether a resource with the given set of OwnerReferences is "adoptable" by +// the target OwnerReference. This function returns true if there exists an element in owners +// referencing the same kind target does, otherwise it returns false. +func Adoptable(target Owner, owners []metav1.OwnerReference) bool { + if len(owners) == 0 { + // Resources with no owners are not adoptable + return false + } + + // Infer TypeMeta for the target + if err := InferGroupVersionKind(target); err != nil { + log.Warn(err.Error()) + } + + for _, owner := range owners { + gvk := target.GetObjectKind().GroupVersionKind() + if owner.Kind == gvk.Kind { + return true + } + } + + return false } // AddNonBlockingOwner adds a nonblocking owner to the ownerref list. func AddNonBlockingOwner(object metav1.Object, owner Owner) { + ownerRefs := object.GetOwnerReferences() + if ownerRefs == nil { + ownerRefs = []metav1.OwnerReference{} + } + + // Infer TypeMeta for the target + if err := InferGroupVersionKind(owner); err != nil { + log.Warn(err.Error()) + } + gvk := owner.GetObjectKind().GroupVersionKind() + + for _, item := range ownerRefs { + if item.Kind == gvk.Kind { + if item.Name == owner.GetName() && item.UID == owner.GetUID() { + return + } + } + } + ownerRefs = append(ownerRefs, NonBlockingOwner(owner)) + object.SetOwnerReferences(ownerRefs) +} + +// NonBlockingOwner returns an ownerrefence to be added to an ownerref list +func NonBlockingOwner(owner Owner) metav1.OwnerReference { // Most of the time we won't have TypeMeta on the object, so we infer it for types we know about - inferGroupVersionKind(owner) - blockOwnerDeletion := false - isController := false + if err := InferGroupVersionKind(owner); err != nil { + log.Warn(err.Error()) + } + + gvk := owner.GetObjectKind().GroupVersionKind() + apiVersion, kind := gvk.ToAPIVersionAndKind() + + return metav1.OwnerReference{ + APIVersion: apiVersion, + Kind: kind, + Name: owner.GetName(), + UID: owner.GetUID(), + BlockOwnerDeletion: &DontBlockOwnerDeletion, + Controller: &NotController, + } +} + +// OwnerLabel returns a label added to generated objects for later querying +func OwnerLabel(owner Owner, kind string) map[string]string { + return map[string]string{ + OwnerKey: owner.GetName(), + OwnerNamespaceKey: owner.GetNamespace(), + OwnerKind: kind, + } +} + +// AddOwnerLabels adds ownerref-like labels to an object +func AddOwnerLabels(object metav1.Object, owner Owner) error { + err := InferGroupVersionKind(owner) + if err != nil { + return err + } + labels := object.GetLabels() + if labels == nil { + labels = map[string]string{} + } + for key, val := range OwnerLabel(owner, owner.GetObjectKind().GroupVersionKind().Kind) { + labels[key] = val + } + object.SetLabels(labels) + return nil +} + +// IsOwnedByKindLabel returns whether or not a label exists on the object pointing to an owner of a particular kind +func IsOwnedByKindLabel(object metav1.Object, ownerKind string) bool { + if object.GetLabels() == nil { + return false + } + return object.GetLabels()[OwnerKind] == ownerKind +} + +// AdoptableLabels determines if an OLM managed resource is adoptable by any of the given targets based on its owner labels. +// The checkName perimeter enables an additional check for name equality with the `olm.owner` label. +// Generally used for cross-namespace ownership and for Cluster -> Namespace scope. +func AdoptableLabels(labels map[string]string, checkName bool, targets ...Owner) bool { + if len(labels) == 0 { + // Resources with no owners are not adoptable + return false + } + + for _, target := range targets { + if err := InferGroupVersionKind(target); err != nil { + log.Warn(err.Error()) + } + if labels[OwnerKind] == target.GetObjectKind().GroupVersionKind().Kind && + labels[OwnerNamespaceKey] == target.GetNamespace() && + (!checkName || labels[OwnerKey] == target.GetName()) { + return true + } + } + + return false +} + +// CSVOwnerSelector returns a label selector to find generated objects owned by owner +func CSVOwnerSelector(owner *v1alpha1.ClusterServiceVersion) labels.Selector { + return labels.SelectorFromSet(OwnerLabel(owner, v1alpha1.ClusterServiceVersionKind)) +} + +// AddOwner adds an owner to the ownerref list. +func AddOwner(object metav1.Object, owner Owner, blockOwnerDeletion, isController bool) { + // Most of the time we won't have TypeMeta on the object, so we infer it for types we know about + if err := InferGroupVersionKind(owner); err != nil { + log.Warn(err.Error()) + } ownerRefs := object.GetOwnerReferences() if ownerRefs == nil { ownerRefs = []metav1.OwnerReference{} } - gvk := owner.GroupVersionKind() + gvk := owner.GetObjectKind().GroupVersionKind() apiVersion, kind := gvk.ToAPIVersionAndKind() ownerRefs = append(ownerRefs, metav1.OwnerReference{ APIVersion: apiVersion, @@ -64,42 +272,95 @@ func AddNonBlockingOwner(object metav1.Object, owner Owner) { object.SetOwnerReferences(ownerRefs) } -// inferGroupVersionKind adds TypeMeta to an owner so that it can be written to an ownerref. +// EnsureOwner adds a new owner if needed and returns whether the object already had the owner. +func EnsureOwner(object metav1.Object, owner Owner) bool { + if IsOwnedBy(object, owner) { + return true + } else { + AddNonBlockingOwner(object, owner) + return false + } +} + +// InferGroupVersionKind adds TypeMeta to an owner so that it can be written to an ownerref. // TypeMeta is generally only known at serialization time, so we often won't know what GVK an owner has. // For the types we know about, we can add the GVK of the apis that we're using the interact with the object. -func inferGroupVersionKind(owner Owner) { - if !owner.GroupVersionKind().Empty() { - // owner already has TypeMeta, no inference needed - return +func InferGroupVersionKind(obj runtime.Object) error { + objectKind := obj.GetObjectKind() + if !objectKind.GroupVersionKind().Empty() { + // objectKind already has TypeMeta, no inference needed + return nil } - switch v := owner.(type) { + switch obj.(type) { + case *corev1.Service: + objectKind.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "Service", + }) + case *corev1.ServiceAccount: + objectKind.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "ServiceAccount", + }) + case *rbac.ClusterRole: + objectKind.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "rbac.authorization.k8s.io", + Version: "v1", + Kind: "ClusterRole", + }) + case *rbac.ClusterRoleBinding: + objectKind.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "rbac.authorization.k8s.io", + Version: "v1", + Kind: "ClusterRoleBinding", + }) + case *rbac.Role: + objectKind.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "rbac.authorization.k8s.io", + Version: "v1", + Kind: "Role", + }) + case *rbac.RoleBinding: + objectKind.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "rbac.authorization.k8s.io", + Version: "v1", + Kind: "RoleBinding", + }) case *v1alpha1.ClusterServiceVersion: - owner.SetGroupVersionKind(schema.GroupVersionKind{ + objectKind.SetGroupVersionKind(schema.GroupVersionKind{ Group: v1alpha1.GroupName, Version: v1alpha1.GroupVersion, Kind: v1alpha1.ClusterServiceVersionKind, }) case *v1alpha1.InstallPlan: - owner.SetGroupVersionKind(schema.GroupVersionKind{ + objectKind.SetGroupVersionKind(schema.GroupVersionKind{ Group: v1alpha1.GroupName, Version: v1alpha1.GroupVersion, Kind: v1alpha1.InstallPlanKind, }) case *v1alpha1.Subscription: - owner.SetGroupVersionKind(schema.GroupVersionKind{ + objectKind.SetGroupVersionKind(schema.GroupVersionKind{ Group: v1alpha1.GroupName, Version: v1alpha1.GroupVersion, Kind: v1alpha1.SubscriptionKind, }) case *v1alpha1.CatalogSource: - owner.SetGroupVersionKind(schema.GroupVersionKind{ + objectKind.SetGroupVersionKind(schema.GroupVersionKind{ Group: v1alpha1.GroupName, Version: v1alpha1.GroupVersion, Kind: v1alpha1.CatalogSourceKind, }) + case *v1.OperatorGroup: + objectKind.SetGroupVersionKind(schema.GroupVersionKind{ + Group: v1.GroupName, + Version: v1.GroupVersion, + Kind: "OperatorGroup", + }) default: - log.Warnf("could not infer GVK for object: %#v, %#v", v, owner) + return fmt.Errorf("could not infer GVK for object: %#v, %#v", obj, objectKind) } - return + return nil } diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/queueinformer/loop_id.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/queueinformer/loop_id.go new file mode 100644 index 0000000000..a909f6c8cd --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/queueinformer/loop_id.go @@ -0,0 +1,14 @@ +package queueinformer + +import ( + "encoding/base64" + "math/rand" +) + +func NewLoopID() string { + len := 5 + buff := make([]byte, len) + rand.Read(buff) + str := base64.StdEncoding.EncodeToString(buff) + return str[:len] +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/queueinformer/queueindexer.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/queueinformer/queueindexer.go new file mode 100644 index 0000000000..6d310670dc --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/queueinformer/queueindexer.go @@ -0,0 +1,65 @@ +package queueinformer + +import ( + "github.com/sirupsen/logrus" + "k8s.io/client-go/tools/cache" + "k8s.io/client-go/util/workqueue" + + "github.com/operator-framework/operator-lifecycle-manager/pkg/metrics" +) + +// QueueIndexer ties an indexer to a queue in order to process events +// the syncHandler is called for all objects on the queue +// Unlike QueueInformer, nothing is automatically adding objects to the queue +type QueueIndexer struct { + queue workqueue.RateLimitingInterface + indexers map[string]cache.Indexer + syncHandler SyncHandler + name string + metrics.MetricsProvider + log *logrus.Logger +} + +// Enqueue adds a key to the queue. If obj is a key already it gets added directly. +// Otherwise, the key is extracted via keyFunc. +func (q *QueueIndexer) Enqueue(obj interface{}) { + if obj == nil { + return + } + + key, ok := obj.(string) + if !ok { + key, ok = q.keyFunc(obj) + if !ok { + return + } + } + + q.queue.Add(key) +} + +func (q *QueueIndexer) Add(key string) { + q.queue.Add(key) +} + +// keyFunc turns an object into a key for the queue. In the future will use a (name, namespace) struct as key +func (q *QueueIndexer) keyFunc(obj interface{}) (string, bool) { + k, err := cache.DeletionHandlingMetaNamespaceKeyFunc(obj) + if err != nil { + q.log.Infof("creating key failed: %s", err) + return k, false + } + + return k, true +} + +func NewQueueIndexer(queue workqueue.RateLimitingInterface, indexers map[string]cache.Indexer, handler SyncHandler, name string, logger *logrus.Logger, provider metrics.MetricsProvider) *QueueIndexer { + return &QueueIndexer{ + queue: queue, + indexers: indexers, + syncHandler: handler, + name: name, + log: logger, + MetricsProvider: provider, + } +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/queueinformer/queueinformer.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/queueinformer/queueinformer.go index 504b53da6c..97f5c2dc34 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/queueinformer/queueinformer.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/queueinformer/queueinformer.go @@ -1,7 +1,8 @@ package queueinformer import ( - log "github.com/sirupsen/logrus" + "github.com/operator-framework/operator-lifecycle-manager/pkg/metrics" + "github.com/sirupsen/logrus" "k8s.io/client-go/tools/cache" "k8s.io/client-go/util/workqueue" ) @@ -18,6 +19,8 @@ type QueueInformer struct { syncHandler SyncHandler resourceEventHandlerFuncs *cache.ResourceEventHandlerFuncs name string + metrics.MetricsProvider + log *logrus.Logger } // enqueue adds a key to the queue. If obj is a key already it gets added directly. @@ -42,70 +45,85 @@ func (q *QueueInformer) enqueue(obj interface{}) { func (q *QueueInformer) keyFunc(obj interface{}) (string, bool) { k, err := cache.DeletionHandlingMetaNamespaceKeyFunc(obj) if err != nil { - log.Infof("creating key failed: %s", err) + q.log.Infof("creating key failed: %s", err) return k, false } return k, true } +func (q *QueueInformer) defaultAddFunc(obj interface{}) { + key, ok := q.keyFunc(obj) + if !ok { + q.log.Warnf("couldn't add %v, couldn't create key", obj) + return + } + + q.enqueue(key) +} + +func (q *QueueInformer) defaultDeleteFunc(obj interface{}) { + key, ok := q.keyFunc(obj) + if !ok { + q.log.Warnf("couldn't delete %v, couldn't create key", obj) + return + } + + q.queue.Forget(key) +} + +func (q *QueueInformer) defaultUpdateFunc(oldObj, newObj interface{}) { + key, ok := q.keyFunc(newObj) + if !ok { + q.log.Warnf("couldn't update %v, couldn't create key", newObj) + return + } + + q.enqueue(key) +} + // defaultResourceEventhandlerFuncs provides the default implementation for responding to events -// these simply log the event and add the object's key to the queue for later processing +// these simply Log the event and add the object's key to the queue for later processing func (q *QueueInformer) defaultResourceEventHandlerFuncs() *cache.ResourceEventHandlerFuncs { return &cache.ResourceEventHandlerFuncs{ - AddFunc: func(obj interface{}) { - key, ok := q.keyFunc(obj) - if !ok { - return - } - - log.Infof("%s added", key) - q.enqueue(key) - }, - DeleteFunc: func(obj interface{}) { - key, ok := q.keyFunc(obj) - if !ok { - return - } - - log.Infof("%s deleted", key) - q.queue.Forget(key) - }, - UpdateFunc: func(oldObj, newObj interface{}) { - key, ok := q.keyFunc(newObj) - if !ok { - return - } - - log.Infof("%s updated", key) - q.enqueue(key) - }, + AddFunc: q.defaultAddFunc, + DeleteFunc: q.defaultDeleteFunc, + UpdateFunc: q.defaultUpdateFunc, } } // New creates a set of new queueinformers given a name, a set of informers, and a sync handler to handle the objects // that the operator is managing. Optionally, custom event handler funcs can be passed in (defaults will be provided) -func New(queue workqueue.RateLimitingInterface, informers []cache.SharedIndexInformer, handler SyncHandler, funcs *cache.ResourceEventHandlerFuncs, name string) []*QueueInformer { +func New(queue workqueue.RateLimitingInterface, informers []cache.SharedIndexInformer, handler SyncHandler, funcs *cache.ResourceEventHandlerFuncs, name string, metrics metrics.MetricsProvider, logger *logrus.Logger) []*QueueInformer { queueInformers := []*QueueInformer{} for _, informer := range informers { - queueInformers = append(queueInformers, NewInformer(queue, informer, handler, funcs, name)) + queueInformers = append(queueInformers, NewInformer(queue, informer, handler, funcs, name, metrics, logger)) } return queueInformers } // NewInformer creates a new queueinformer given a name, an informer, and a sync handler to handle the objects // that the operator is managing. Optionally, custom event handler funcs can be passed in (defaults will be provided) -func NewInformer(queue workqueue.RateLimitingInterface, informer cache.SharedIndexInformer, handler SyncHandler, funcs *cache.ResourceEventHandlerFuncs, name string) *QueueInformer { +func NewInformer(queue workqueue.RateLimitingInterface, informer cache.SharedIndexInformer, handler SyncHandler, funcs *cache.ResourceEventHandlerFuncs, name string, metrics metrics.MetricsProvider, logger *logrus.Logger) *QueueInformer { queueInformer := &QueueInformer{ - queue: queue, - informer: informer, - syncHandler: handler, - name: name, + queue: queue, + informer: informer, + syncHandler: handler, + name: name, + MetricsProvider: metrics, + log: logger, } - if funcs == nil { - queueInformer.resourceEventHandlerFuncs = queueInformer.defaultResourceEventHandlerFuncs() - } else { - queueInformer.resourceEventHandlerFuncs = funcs + queueInformer.resourceEventHandlerFuncs = queueInformer.defaultResourceEventHandlerFuncs() + if funcs != nil { + if funcs.AddFunc != nil { + queueInformer.resourceEventHandlerFuncs.AddFunc = funcs.AddFunc + } + if funcs.DeleteFunc != nil { + queueInformer.resourceEventHandlerFuncs.DeleteFunc = funcs.DeleteFunc + } + if funcs.UpdateFunc != nil { + queueInformer.resourceEventHandlerFuncs.UpdateFunc = funcs.UpdateFunc + } } queueInformer.informer.AddEventHandler(queueInformer.resourceEventHandlerFuncs) return queueInformer diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/queueinformer/queueinformer_operator.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/queueinformer/queueinformer_operator.go index fa08ba7e9f..779e4093cf 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/queueinformer/queueinformer_operator.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/queueinformer/queueinformer_operator.go @@ -3,40 +3,48 @@ package queueinformer import ( "fmt" - "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient" "github.com/pkg/errors" - log "github.com/sirupsen/logrus" + "github.com/sirupsen/logrus" + v1 "k8s.io/api/core/v1" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/client-go/tools/cache" + + "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient" ) // An Operator is a collection of QueueInformers // OpClient is used to establish the connection to kubernetes type Operator struct { queueInformers []*QueueInformer + queueIndexers []*QueueIndexer + informers []cache.SharedIndexInformer OpClient operatorclient.ClientInterface + Log *logrus.Logger + syncCh chan error } // NewOperator creates a new Operator configured to manage the cluster defined in kubeconfig. -func NewOperator(kubeconfig string, queueInformers ...*QueueInformer) (*Operator, error) { - opClient := operatorclient.NewClientFromConfig(kubeconfig) +func NewOperator(kubeconfig string, logger *logrus.Logger, queueInformers ...*QueueInformer) (*Operator, error) { + opClient := operatorclient.NewClientFromConfig(kubeconfig, logger) if queueInformers == nil { queueInformers = []*QueueInformer{} } operator := &Operator{ OpClient: opClient, queueInformers: queueInformers, + Log: logger, } return operator, nil } -func NewOperatorFromClient(opClient operatorclient.ClientInterface, queueInformers ...*QueueInformer) (*Operator, error) { +func NewOperatorFromClient(opClient operatorclient.ClientInterface, logger *logrus.Logger, queueInformers ...*QueueInformer) (*Operator, error) { if queueInformers == nil { queueInformers = []*QueueInformer{} } operator := &Operator{ OpClient: opClient, queueInformers: queueInformers, + Log: logger, } return operator, nil } @@ -49,54 +57,101 @@ func (o *Operator) RegisterQueueInformer(queueInformer *QueueInformer) { o.queueInformers = append(o.queueInformers, queueInformer) } -// Run starts the operator's control loops -func (o *Operator) Run(stopc <-chan struct{}) error { - for _, queueInformer := range o.queueInformers { - defer queueInformer.queue.ShutDown() +// RegisterInformer adds an Informer to this operator +func (o *Operator) RegisterInformer(informer cache.SharedIndexInformer) { + if o.informers == nil { + o.informers = []cache.SharedIndexInformer{} + } + o.informers = append(o.informers, informer) +} + +// RegisterQueueIndexer adds a QueueIndexer to this operator +func (o *Operator) RegisterQueueIndexer(indexer *QueueIndexer) { + if o.queueIndexers == nil { + o.queueIndexers = []*QueueIndexer{} } + o.queueIndexers = append(o.queueIndexers, indexer) +} + +// Run starts the operator's control loops +func (o *Operator) Run(stopc <-chan struct{}) (ready, done chan struct{}, atLevel chan error) { + ready = make(chan struct{}) + atLevel = make(chan error, 25) + done = make(chan struct{}) + + o.syncCh = atLevel - errChan := make(chan error) go func() { - v, err := o.OpClient.KubernetesInterface().Discovery().ServerVersion() - if err != nil { - errChan <- errors.Wrap(err, "communicating with server failed") + defer func() { + close(ready) + close(atLevel) + close(done) + }() + + for _, queueInformer := range o.queueInformers { + defer queueInformer.queue.ShutDown() + } + + errChan := make(chan error) + go func() { + v, err := o.OpClient.KubernetesInterface().Discovery().ServerVersion() + if err != nil { + errChan <- errors.Wrap(err, "communicating with server failed") + return + } + o.Log.Infof("connection established. cluster-version: %v", v) + errChan <- nil + }() + + var hasSyncedCheckFns []cache.InformerSynced + for _, queueInformer := range o.queueInformers { + hasSyncedCheckFns = append(hasSyncedCheckFns, queueInformer.informer.HasSynced) + } + for _, informer := range o.informers { + hasSyncedCheckFns = append(hasSyncedCheckFns, informer.HasSynced) + } + + select { + case err := <-errChan: + if err != nil { + o.Log.Infof("operator not ready: %s", err.Error()) + return + } + o.Log.Info("operator ready") + case <-stopc: return } - log.Infof("connection established. cluster-version: %v", v) - errChan <- nil - }() - var hasSyncedCheckFns []cache.InformerSynced - for _, queueInformer := range o.queueInformers { - hasSyncedCheckFns = append(hasSyncedCheckFns, queueInformer.informer.HasSynced) - } + o.Log.Info("starting informers...") + for _, queueInformer := range o.queueInformers { + go queueInformer.informer.Run(stopc) + } - select { - case err := <-errChan: - if err != nil { - return err + for _, informer := range o.informers { + go informer.Run(stopc) } - log.Info("Operator ready") - case <-stopc: - return nil - } - log.Info("starting informers...") - for _, queueInformer := range o.queueInformers { - go queueInformer.informer.Run(stopc) - } + o.Log.Info("waiting for caches to sync...") + if ok := cache.WaitForCacheSync(stopc, hasSyncedCheckFns...); !ok { + o.Log.Info("failed to wait for caches to sync") + return + } - log.Info("waiting for caches to sync...") - if ok := cache.WaitForCacheSync(stopc, hasSyncedCheckFns...); !ok { - return fmt.Errorf("failed to wait for caches to sync") - } + o.Log.Info("starting workers...") + for _, queueInformer := range o.queueInformers { + go o.worker(queueInformer) + go o.worker(queueInformer) + } - log.Info("starting workers...") - for _, queueInformer := range o.queueInformers { - go o.worker(queueInformer) - } - <-stopc - return nil + for _, queueIndexer := range o.queueIndexers { + go o.indexerWorker(queueIndexer) + go o.indexerWorker(queueIndexer) + } + ready <- struct{}{} + <-stopc + }() + + return } // worker runs a worker thread that just dequeues items, processes them, and marks them done. @@ -116,24 +171,32 @@ func (o *Operator) processNextWorkItem(loop *QueueInformer) bool { defer queue.Done(key) // requeue five times on error - if err := o.sync(loop, key.(string)); err != nil && queue.NumRequeues(key.(string)) < 5 { - log.Infof("retrying %s", key) + err := o.sync(loop, key.(string)) + if err != nil && queue.NumRequeues(key.(string)) < 5 { + o.Log.Infof("retrying %s", key) utilruntime.HandleError(errors.Wrap(err, fmt.Sprintf("Sync %q failed", key))) queue.AddRateLimited(key) return true } queue.Forget(key) + + select { + case o.syncCh <- err: + default: + } + + if err := loop.HandleMetrics(); err != nil { + o.Log.Error(err) + } return true } func (o *Operator) sync(loop *QueueInformer, key string) error { - logger := log.WithField("queue", loop.name).WithField("key", key) - logger.Info("getting from queue") + logger := o.Log.WithField("queue", loop.name).WithField("key", key) obj, exists, err := loop.informer.GetIndexer().GetByKey(key) if err != nil { return err } - if !exists { // For now, we ignore the case where an object used to exist but no longer does logger.Info("couldn't get from queue") @@ -142,3 +205,60 @@ func (o *Operator) sync(loop *QueueInformer, key string) error { } return loop.syncHandler(obj) } + +// This provides the same function as above, but for queues that are not auto-fed by informers. +// indexerWorker runs a worker thread that just dequeues items, processes them, and marks them done. +// It enforces that the syncHandler is never invoked concurrently with the same key. +func (o *Operator) indexerWorker(loop *QueueIndexer) { + for o.processNextIndexerWorkItem(loop) { + } +} + +func (o *Operator) processNextIndexerWorkItem(loop *QueueIndexer) bool { + queue := loop.queue + key, quit := queue.Get() + + if quit { + return false + } + defer queue.Done(key) + + // requeue five times on error + if err := o.syncIndexer(loop, key.(string)); err != nil && queue.NumRequeues(key.(string)) < 5 { + o.Log.Infof("retrying %s", key) + utilruntime.HandleError(errors.Wrap(err, fmt.Sprintf("Sync %q failed", key))) + queue.AddRateLimited(key) + return true + } + queue.Forget(key) + if err := loop.HandleMetrics(); err != nil { + o.Log.Error(err) + } + return true +} + +func (o *Operator) syncIndexer(loop *QueueIndexer, key string) error { + logger := o.Log.WithField("queue", loop.name).WithField("key", key) + namespace, _, err := cache.SplitMetaNamespaceKey(key) + if err != nil { + return err + } + + indexer, ok := loop.indexers[namespace] + if !ok { + if indexer, ok = loop.indexers[v1.NamespaceAll]; !ok { + return fmt.Errorf("no indexer found for %s, have %v", namespace, loop.indexers) + } + } + obj, exists, err := indexer.GetByKey(key) + if err != nil { + return err + } + if !exists { + // For now, we ignore the case where an object used to exist but no longer does + logger.Info("couldn't get from queue") + logger.Debugf("have keys: %v", indexer.ListKeys()) + return nil + } + return loop.syncHandler(obj) +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/queueinformer/resourcequeue.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/queueinformer/resourcequeue.go new file mode 100644 index 0000000000..08f4ea4424 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/queueinformer/resourcequeue.go @@ -0,0 +1,98 @@ +package queueinformer + +import ( + "fmt" + "strings" + "sync" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/util/workqueue" +) + +// ResourceQueueSet is a set of workqueues that is assumed to be keyed by namespace +type ResourceQueueSet struct { + queueSet map[string]workqueue.RateLimitingInterface + mutex sync.RWMutex +} + +// NewResourceQueueSet returns a new queue set with the given queue map +func NewResourceQueueSet(queueSet map[string]workqueue.RateLimitingInterface) *ResourceQueueSet { + return &ResourceQueueSet{queueSet: queueSet} +} + +// NewEmptyResourceQueueSet returns a new queue set with an empty but initialized queue map +func NewEmptyResourceQueueSet() *ResourceQueueSet { + return &ResourceQueueSet{queueSet: make(map[string]workqueue.RateLimitingInterface)} +} + +// Set sets the queue at the given key +func (r *ResourceQueueSet) Set(key string, queue workqueue.RateLimitingInterface) { + r.mutex.Lock() + defer r.mutex.Unlock() + r.queueSet[key] = queue +} + +// Requeue requeues the resource in the set with the given name and namespace +func (r *ResourceQueueSet) Requeue(name, namespace string) error { + r.mutex.RLock() + defer r.mutex.RUnlock() + + // We can build the key directly, will need to change if queue uses different key scheme + key := fmt.Sprintf("%s/%s", namespace, name) + + if queue, ok := r.queueSet[metav1.NamespaceAll]; len(r.queueSet) == 1 && ok { + queue.Add(key) + return nil + } + + if queue, ok := r.queueSet[namespace]; ok { + queue.Add(key) + return nil + } + + return fmt.Errorf("couldn't find queue for resource") +} + +// RequeueByKey adds the given key to the resource queue that should contain it +func (r *ResourceQueueSet) RequeueByKey(key string) error { + r.mutex.RLock() + defer r.mutex.RUnlock() + + if queue, ok := r.queueSet[metav1.NamespaceAll]; len(r.queueSet) == 1 && ok { + queue.Add(key) + return nil + } + + parts := strings.Split(key, "/") + if len(parts) != 2 { + return fmt.Errorf("non-namespaced key %s cannot be used with namespaced queues", key) + } + + if queue, ok := r.queueSet[parts[0]]; ok { + queue.Add(key) + return nil + } + + return fmt.Errorf("couldn't find queue for resource") +} + +// Remove removes the resource in the set with the given name and namespace +func (r *ResourceQueueSet) Remove(name, namespace string) error { + r.mutex.RLock() + defer r.mutex.RUnlock() + + // We can build the key directly, will need to change if queue uses different key scheme + key := fmt.Sprintf("%s/%s", namespace, name) + + if queue, ok := r.queueSet[metav1.NamespaceAll]; len(r.queueSet) == 1 && ok { + queue.Forget(key) + return nil + } + + if queue, ok := r.queueSet[namespace]; ok { + queue.Forget(key) + return nil + } + + return fmt.Errorf("couldn't find queue for resource") +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/schema/schema.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/schema/schema.go deleted file mode 100644 index b4df500b0d..0000000000 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/schema/schema.go +++ /dev/null @@ -1,319 +0,0 @@ -package schema - -import ( - "bufio" - "bytes" - "encoding/json" - "fmt" - "io/ioutil" - "os" - "path/filepath" - "strings" - - "github.com/ghodss/yaml" - "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" - "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" - "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation" - apiservervalidation "k8s.io/apiextensions-apiserver/pkg/apiserver/validation" - apiValidation "k8s.io/apimachinery/pkg/api/validation" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime" - - "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" - "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry" - "k8s.io/apimachinery/pkg/conversion" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/util/validation/field" -) - -func readPragmas(fileBytes []byte) (pragmas []string, err error) { - fileReader := bytes.NewReader(fileBytes) - fileBufReader := bufio.NewReader(fileReader) - for { - maybePragma, err := fileBufReader.ReadString('\n') - if err != nil { - return nil, err - } - if strings.HasPrefix(maybePragma, "#!") { - pragmas = append(pragmas, strings.TrimSpace(strings.TrimPrefix(maybePragma, "#!"))) - } else { - // pragmas must be defined at the top of the file, stop when we don't see a line with the pragma mark - break - } - } - return -} - -type Meta struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata"` -} - -func (m *Meta) GetObjectKind() schema.ObjectKind { - return m -} -func (in *Meta) DeepCopyInto(out *Meta) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - return -} - -func (in *Meta) DeepCopy() *Meta { - if in == nil { - return nil - } - out := new(Meta) - in.DeepCopyInto(out) - return out -} - -func (in *Meta) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } else { - return nil - } -} - -func validateKubectlable(fileBytes []byte) error { - exampleFileBytesJson, err := yaml.YAMLToJSON(fileBytes) - if err != nil { - return err - } - parsedMeta := &Meta{} - err = json.Unmarshal(exampleFileBytesJson, parsedMeta) - if err != nil { - return err - } - requiresNamespace := parsedMeta.Kind != "CustomResourceDefinition" - errs := apiValidation.ValidateObjectMeta( - &parsedMeta.ObjectMeta, - requiresNamespace, - func(s string, prefix bool) []string { - return nil - }, - field.NewPath("metadata"), - ) - - if len(errs) > 0 { - return fmt.Errorf("error validating object metadata: %s. %v. %s", errs, parsedMeta, string(exampleFileBytesJson)) - } - return nil -} - -func validateUsingPragma(pragma string, fileBytes []byte) (bool, error) { - const validateCRDPrefix = "validate-crd:" - const ParseAsKindPrefix = "parse-kind:" - const PackageManifest = "package-manifest:" - - switch { - case strings.HasPrefix(pragma, validateCRDPrefix): - return true, validateCRD(strings.TrimSpace(strings.TrimPrefix(pragma, validateCRDPrefix)), fileBytes) - case strings.HasPrefix(pragma, ParseAsKindPrefix): - return true, validateKind(strings.TrimSpace(strings.TrimPrefix(pragma, ParseAsKindPrefix)), fileBytes) - case strings.HasPrefix(pragma, PackageManifest): - csvFilenames := strings.Split(strings.TrimSpace(strings.TrimPrefix(pragma, PackageManifest)), ",") - return false, validatePackageManifest(fileBytes, csvFilenames) - } - return false, nil -} - -func validatePackageManifest(fileBytes []byte, csvFilenames []string) error { - manifestBytesJson, err := yaml.YAMLToJSON(fileBytes) - if err != nil { - return err - } - - var packageManifest registry.PackageManifest - err = json.Unmarshal(manifestBytesJson, &packageManifest) - if err != nil { - return err - } - - if len(packageManifest.Channels) < 1 { - return fmt.Errorf("Package manifest validation failure for package %s: Missing channels", packageManifest.PackageName) - } - - // Collect the defined CSV names. - csvNames := map[string]bool{} - for _, csvFilename := range csvFilenames { - csvBytes, err := ioutil.ReadFile(csvFilename) - if err != nil { - return err - } - - csvBytesJson, err := yaml.YAMLToJSON(csvBytes) - if err != nil { - return err - } - - csv := v1alpha1.ClusterServiceVersion{} - err = json.Unmarshal(csvBytesJson, &csv) - if err != nil { - return err - } - - csvNames[csv.Name] = true - } - - if len(packageManifest.PackageName) == 0 { - return fmt.Errorf("Empty package name") - } - - // Make sure that each channel name is unique and that the referenced CSV exists. - channelMap := make(map[string]bool, len(packageManifest.Channels)) - for _, channel := range packageManifest.Channels { - if _, exists := channelMap[channel.Name]; exists { - return fmt.Errorf("Channel %s declared twice in package manifest", channel.Name) - } - - if _, ok := csvNames[channel.CurrentCSVName]; !ok { - return fmt.Errorf("Missing CSV with name %s", channel.CurrentCSVName) - } - - channelMap[channel.Name] = true - } - - return nil -} - -func validateCRD(schemaFileName string, fileBytes []byte) error { - schemaBytes, err := ioutil.ReadFile(schemaFileName) - if err != nil { - return err - } - schemaBytesJson, err := yaml.YAMLToJSON(schemaBytes) - if err != nil { - return err - } - - crd := v1beta1.CustomResourceDefinition{} - json.Unmarshal(schemaBytesJson, &crd) - - exampleFileBytesJson, err := yaml.YAMLToJSON(fileBytes) - if err != nil { - return err - } - unstructured := unstructured.Unstructured{} - err = json.Unmarshal(exampleFileBytesJson, &unstructured) - if err != nil { - return err - } - - // Validate CRD definition statically - scheme := runtime.NewScheme() - err = apiextensions.AddToScheme(scheme) - if err != nil { - return err - } - err = v1beta1.AddToScheme(scheme) - if err != nil { - return err - } - - unversionedCRD := apiextensions.CustomResourceDefinition{} - scheme.Converter().Convert(&crd, &unversionedCRD, conversion.SourceToDest, nil) - errList := validation.ValidateCustomResourceDefinition(&unversionedCRD) - if len(errList) > 0 { - for _, ferr := range errList { - fmt.Println(ferr) - } - return fmt.Errorf("CRD failed validation: %s. Errors: %s", schemaFileName, errList) - } - - // Validate CR against CRD schema - validator, _, err := apiservervalidation.NewSchemaValidator(unversionedCRD.Spec.Validation) - return apiservervalidation.ValidateCustomResource(unstructured.UnstructuredContent(), validator) -} - -func validateKind(kind string, fileBytes []byte) error { - exampleFileBytesJson, err := yaml.YAMLToJSON(fileBytes) - if err != nil { - return err - } - - switch kind { - case "ClusterServiceVersion": - csv := v1alpha1.ClusterServiceVersion{} - err = json.Unmarshal(exampleFileBytesJson, &csv) - if err != nil { - return err - } - return err - case "CatalogSource": - cs := v1alpha1.CatalogSource{} - err = json.Unmarshal(exampleFileBytesJson, &cs) - if err != nil { - return err - } - return err - default: - return fmt.Errorf("didn't recognize validate-kind directive: %s", kind) - } -} - -func validateResource(path string, f os.FileInfo, err error) error { - if err != nil { - return err - } - - exampleFileReader, err := os.Open(path) - if err != nil { - return err - } - defer exampleFileReader.Close() - - fileReader := bufio.NewReader(exampleFileReader) - fileBytes, err := ioutil.ReadAll(fileReader) - if err != nil { - return err - } - pragmas, err := readPragmas(fileBytes) - if err != nil { - return err - } - - isKubResource := false - for _, pragma := range pragmas { - fileReader.Reset(exampleFileReader) - isKub, err := validateUsingPragma(pragma, fileBytes) - if err != nil { - return fmt.Errorf("validating %s: %v", path, err) - } - isKubResource = isKubResource || isKub - } - - if isKubResource { - err = validateKubectlable(fileBytes) - if err != nil { - return fmt.Errorf("validating %s: %v", path, err) - } - } - return nil -} - -func validateResources(directory string) error { - err := filepath.Walk(directory, func(path string, f os.FileInfo, err error) error { - if f.IsDir() { - return nil - } - - if !strings.HasSuffix(path, ".yaml") { - return nil - } - - fmt.Printf("validate %s\n", path) - if validateResource(path, f, err) != nil { - return err - } - - return nil - }) - return err -} - -func CheckCatalogResources(manifestDir string) error { - return validateResources(manifestDir) -} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/schema/upgrade_path.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/schema/upgrade_path.go deleted file mode 100644 index d766b45e67..0000000000 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/schema/upgrade_path.go +++ /dev/null @@ -1,66 +0,0 @@ -package schema - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "path/filepath" - - "github.com/ghodss/yaml" - - "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" -) - -// Files is a map of files. -type Files map[string][]byte - -// Glob searches the `/manifests` directory for files matching the pattern and returns them. -func Glob(pattern string) (Files, error) { - matching := map[string][]byte{} - files, err := filepath.Glob(pattern) - if err != nil { - return nil, err - } - - for _, name := range files { - bytes, err := ioutil.ReadFile(name) - if err != nil { - return nil, err - } - matching[name] = bytes - } - - return matching, nil -} - -// CheckUpgradePath checks that every ClusterServiceVersion in a package directory has a valid `spec.replaces` field. -func CheckUpgradePath(packageDir string) error { - replaces := map[string]string{} - csvFiles, err := Glob(filepath.Join(packageDir, "**.clusterserviceversion.yaml")) - if err != nil { - return err - } - - for _, bytes := range csvFiles { - jsonBytes, err := yaml.YAMLToJSON(bytes) - if err != nil { - return err - } - var csv v1alpha1.ClusterServiceVersion - err = json.Unmarshal(jsonBytes, &csv) - if err != nil { - return err - } - replaces[csv.ObjectMeta.Name] = csv.Spec.Replaces - } - - for replacing, replaced := range replaces { - fmt.Printf("%s -> %s\n", replaced, replacing) - - if _, ok := replaces[replaced]; replaced != "" && !ok { - err := fmt.Errorf("%s should replace %s, which does not exist", replacing, replaced) - return err - } - } - return nil -} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/metrics/metrics.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/metrics/metrics.go new file mode 100644 index 0000000000..29a11bbc98 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/metrics/metrics.go @@ -0,0 +1,146 @@ +package metrics + +import ( + "github.com/prometheus/client_golang/prometheus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + + "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned" + v1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1alpha1" +) + +// TODO(alecmerdler): Can we use this to emit Kubernetes events? +type MetricsProvider interface { + HandleMetrics() error +} + +type metricsCSV struct { + lister v1alpha1.ClusterServiceVersionLister +} + +func NewMetricsCSV(lister v1alpha1.ClusterServiceVersionLister) MetricsProvider { + return &metricsCSV{lister} +} + +func (m *metricsCSV) HandleMetrics() error { + cList, err := m.lister.List(labels.Everything()) + if err != nil { + return err + } + csvCount.Set(float64(len(cList))) + return nil +} + +type metricsInstallPlan struct { + client versioned.Interface +} + +func NewMetricsInstallPlan(client versioned.Interface) MetricsProvider { + return &metricsInstallPlan{client} +} + +func (m *metricsInstallPlan) HandleMetrics() error { + cList, err := m.client.OperatorsV1alpha1().InstallPlans(metav1.NamespaceAll).List(metav1.ListOptions{}) + if err != nil { + return err + } + installPlanCount.Set(float64(len(cList.Items))) + return nil +} + +type metricsSubscription struct { + client versioned.Interface +} + +func NewMetricsSubscription(client versioned.Interface) MetricsProvider { + return &metricsSubscription{client} +} + +func (m *metricsSubscription) HandleMetrics() error { + cList, err := m.client.OperatorsV1alpha1().Subscriptions(metav1.NamespaceAll).List(metav1.ListOptions{}) + if err != nil { + return err + } + subscriptionCount.Set(float64(len(cList.Items))) + return nil +} + +type metricsCatalogSource struct { + client versioned.Interface +} + +func NewMetricsCatalogSource(client versioned.Interface) MetricsProvider { + return &metricsCatalogSource{client} + +} + +func (m *metricsCatalogSource) HandleMetrics() error { + cList, err := m.client.OperatorsV1alpha1().CatalogSources(metav1.NamespaceAll).List(metav1.ListOptions{}) + if err != nil { + return err + } + catalogSourceCount.Set(float64(len(cList.Items))) + return nil +} + +type MetricsNil struct{} + +func NewMetricsNil() MetricsProvider { + return &MetricsNil{} +} + +func (*MetricsNil) HandleMetrics() error { + return nil +} + +// To add new metrics: +// 1. Register new metrics in Register() below. +// 2. Add appropriate metric updates in HandleMetrics (or elsewhere instead). +var ( + csvCount = prometheus.NewGauge( + prometheus.GaugeOpts{ + Name: "csv_count", + Help: "Number of CSVs successfully registered", + }, + ) + + installPlanCount = prometheus.NewGauge( + prometheus.GaugeOpts{ + Name: "install_plan_count", + Help: "Number of install plans", + }, + ) + + subscriptionCount = prometheus.NewGauge( + prometheus.GaugeOpts{ + Name: "subscription_count", + Help: "Number of subscriptions", + }, + ) + + catalogSourceCount = prometheus.NewGauge( + prometheus.GaugeOpts{ + Name: "catalog_source_count", + Help: "Number of catalog sources", + }, + ) + + // exported since it's not handled by HandleMetrics + CSVUpgradeCount = prometheus.NewCounter( + prometheus.CounterOpts{ + Name: "csv_upgrade_count", + Help: "Monotonic count of CSV upgrades", + }, + ) +) + +func RegisterOLM() { + prometheus.MustRegister(csvCount) + prometheus.MustRegister(CSVUpgradeCount) +} + +func RegisterCatalog() { + prometheus.MustRegister(installPlanCount) + prometheus.MustRegister(subscriptionCount) + prometheus.MustRegister(catalogSourceCount) +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/doc.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/doc.go new file mode 100644 index 0000000000..b098b2042d --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/doc.go @@ -0,0 +1,2 @@ +// Package apps is the internal version of the API. +package apps diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/install/install.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/install/install.go new file mode 100644 index 0000000000..36626aa271 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/install/install.go @@ -0,0 +1,16 @@ +package install + +import ( + "k8s.io/apimachinery/pkg/runtime" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + + "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps" + "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1" +) + +// Install registers API groups and adds types to a scheme. +func Install(scheme *runtime.Scheme) { + utilruntime.Must(apps.AddToScheme(scheme)) + utilruntime.Must(v1alpha1.AddToScheme(scheme)) + utilruntime.Must(scheme.SetVersionPriority(v1alpha1.SchemeGroupVersion)) +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/register.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/register.go new file mode 100644 index 0000000000..1598139f97 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/register.go @@ -0,0 +1,38 @@ +package apps + +import ( + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + + "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators" +) + +var ( + Group = "packages.apps.redhat.com" + + // SchemeGroupVersion is the GroupVersion used to register this object + SchemeGroupVersion = schema.GroupVersion{Group: Group, Version: runtime.APIVersionInternal} + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + AddToScheme = SchemeBuilder.AddToScheme +) + +// Kind takes an unqualified kind and returns the group-qualified kind. +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns the group-qualified resource. +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +// addKnownTypes adds the set of types defined in this package to the supplied scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + // Add types for each GroupVersion + scheme.AddKnownTypes(SchemeGroupVersion, + &operators.PackageManifest{}, + &operators.PackageManifestList{}, + ) + + return nil +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1/doc.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1/doc.go new file mode 100644 index 0000000000..39fd1d18b5 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1/doc.go @@ -0,0 +1,7 @@ +// +k8s:deepcopy-gen=package +// +k8s:conversion-gen=github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators +// +k8s:defaulter-gen=TypeMeta +// +k8s:openapi-gen=true + +// +groupName=apps.redhat.com +package v1alpha1 diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1/packagemanifest_types.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1/packagemanifest_types.go similarity index 71% rename from vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1/packagemanifest_types.go rename to vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1/packagemanifest_types.go index c7830ddd51..ee92f75963 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1/packagemanifest_types.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1/packagemanifest_types.go @@ -3,6 +3,8 @@ package v1alpha1 import ( "github.com/coreos/go-semver/semver" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + operatorv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" ) // PackageManifestList is a list of PackageManifest objects. @@ -31,8 +33,10 @@ type PackageManifestSpec struct{} // PackageManifestStatus represents the current status of the PackageManifest type PackageManifestStatus struct { - // CatalogSourceName is the name of the CatalogSource this package belongs to - CatalogSourceName string `json:"catalogSource"` + // CatalogSource is the name of the CatalogSource this package belongs to + CatalogSource string `json:"catalogSource"` + CatalogSourceDisplayName string `json:"catalogSourceDisplayName"` + CatalogSourcePublisher string `json:"catalogSourcePublisher"` // CatalogSourceNamespace is the namespace of the owning CatalogSource CatalogSourceNamespace string `json:"catalogSourceNamespace"` @@ -46,17 +50,17 @@ type PackageManifestStatus struct { // Channels are the declared channels for the package, ala `stable` or `alpha`. Channels []PackageChannel `json:"channels"` - // DefaultChannelName is, if specified, the name of the default channel for the package. The + // DefaultChannel is, if specified, the name of the default channel for the package. The // default channel will be installed if no other channel is explicitly given. If the package // has a single channel, then that channel is implicitly the default. - DefaultChannelName string `json:"defaultChannel"` + DefaultChannel string `json:"defaultChannel"` } // GetDefaultChannel gets the default channel or returns the only one if there's only one. returns empty string if it // can't determine the default func (m PackageManifest) GetDefaultChannel() string { - if m.Status.DefaultChannelName != "" { - return m.Status.DefaultChannelName + if m.Status.DefaultChannel != "" { + return m.Status.DefaultChannel } if len(m.Status.Channels) == 1 { return m.Status.Channels[0].Name @@ -70,9 +74,9 @@ type PackageChannel struct { // Name is the name of the channel, e.g. `alpha` or `stable` Name string `json:"name"` - // CurrentCSVName defines a reference to the CSV holding the version of this package currently + // CurrentCSV defines a reference to the CSV holding the version of this package currently // for the channel. - CurrentCSVName string `json:"currentCSV"` + CurrentCSV string `json:"currentCSV"` // CurrentCSVSpec holds the spec of the current CSV CurrentCSVDesc CSVDescription `json:"currentCSVDesc,omitempty"` @@ -91,7 +95,14 @@ type CSVDescription struct { Version semver.Version `json:"version,omitempty"` // Provider is the CSV's provider - Provider AppLink `json:"provider,omitempty"` + Provider AppLink `json:"provider,omitempty"` + Annotations map[string]string `json:"annotations,omitempty"` + + // LongDescription is the CSV's description + LongDescription string `json:"description,omitempty"` + + // InstallModes specify supported installation types + InstallModes []operatorv1alpha1.InstallMode `json:"installModes,omitempty"` } // AppLink defines a link to an application @@ -102,11 +113,11 @@ type AppLink struct { // Icon defines a base64 encoded icon and media type type Icon struct { - Data string `json:"base64data,omitempty"` - MediaType string `json:"mediatype,omitempty"` + Base64Data string `json:"base64data,omitempty"` + Mediatype string `json:"mediatype,omitempty"` } // IsDefaultChannel returns true if the PackageChannel is the default for the PackageManifest func (pc PackageChannel) IsDefaultChannel(pm PackageManifest) bool { - return pc.Name == pm.Status.DefaultChannelName || len(pm.Status.Channels) == 1 + return pc.Name == pm.Status.DefaultChannel || len(pm.Status.Channels) == 1 } diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1/register.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1/register.go similarity index 88% rename from vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1/register.go rename to vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1/register.go index 58fa2ad1a0..9e40864684 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1/register.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1/register.go @@ -6,11 +6,6 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" ) -var ( - SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) - AddToScheme = SchemeBuilder.AddToScheme -) - const ( Group = "packages.apps.redhat.com" Version = "v1alpha1" @@ -21,6 +16,12 @@ const ( // SchemeGroupVersion is the group version used to register these objects. var SchemeGroupVersion = schema.GroupVersion{Group: Group, Version: Version} +var ( + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + localSchemeBuilder = &SchemeBuilder + AddToScheme = localSchemeBuilder.AddToScheme +) + // 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/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1/zz_generated.conversion.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1/zz_generated.conversion.go new file mode 100644 index 0000000000..cb22134acf --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1/zz_generated.conversion.go @@ -0,0 +1,338 @@ +// +build !ignore_autogenerated + +/* +Copyright 2019 Red Hat, 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 conversion-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + unsafe "unsafe" + + operatorsv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + operators "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators" + conversion "k8s.io/apimachinery/pkg/conversion" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +func init() { + localSchemeBuilder.Register(RegisterConversions) +} + +// RegisterConversions adds conversion functions to the given scheme. +// Public to allow building arbitrary schemes. +func RegisterConversions(s *runtime.Scheme) error { + if err := s.AddGeneratedConversionFunc((*AppLink)(nil), (*operators.AppLink)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_AppLink_To_operators_AppLink(a.(*AppLink), b.(*operators.AppLink), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*operators.AppLink)(nil), (*AppLink)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_operators_AppLink_To_v1alpha1_AppLink(a.(*operators.AppLink), b.(*AppLink), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*CSVDescription)(nil), (*operators.CSVDescription)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_CSVDescription_To_operators_CSVDescription(a.(*CSVDescription), b.(*operators.CSVDescription), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*operators.CSVDescription)(nil), (*CSVDescription)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_operators_CSVDescription_To_v1alpha1_CSVDescription(a.(*operators.CSVDescription), b.(*CSVDescription), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*Icon)(nil), (*operators.Icon)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_Icon_To_operators_Icon(a.(*Icon), b.(*operators.Icon), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*operators.Icon)(nil), (*Icon)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_operators_Icon_To_v1alpha1_Icon(a.(*operators.Icon), b.(*Icon), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*PackageChannel)(nil), (*operators.PackageChannel)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_PackageChannel_To_operators_PackageChannel(a.(*PackageChannel), b.(*operators.PackageChannel), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*operators.PackageChannel)(nil), (*PackageChannel)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_operators_PackageChannel_To_v1alpha1_PackageChannel(a.(*operators.PackageChannel), b.(*PackageChannel), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*PackageManifest)(nil), (*operators.PackageManifest)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_PackageManifest_To_operators_PackageManifest(a.(*PackageManifest), b.(*operators.PackageManifest), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*operators.PackageManifest)(nil), (*PackageManifest)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_operators_PackageManifest_To_v1alpha1_PackageManifest(a.(*operators.PackageManifest), b.(*PackageManifest), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*PackageManifestList)(nil), (*operators.PackageManifestList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_PackageManifestList_To_operators_PackageManifestList(a.(*PackageManifestList), b.(*operators.PackageManifestList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*operators.PackageManifestList)(nil), (*PackageManifestList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_operators_PackageManifestList_To_v1alpha1_PackageManifestList(a.(*operators.PackageManifestList), b.(*PackageManifestList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*PackageManifestSpec)(nil), (*operators.PackageManifestSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_PackageManifestSpec_To_operators_PackageManifestSpec(a.(*PackageManifestSpec), b.(*operators.PackageManifestSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*operators.PackageManifestSpec)(nil), (*PackageManifestSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_operators_PackageManifestSpec_To_v1alpha1_PackageManifestSpec(a.(*operators.PackageManifestSpec), b.(*PackageManifestSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*PackageManifestStatus)(nil), (*operators.PackageManifestStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_PackageManifestStatus_To_operators_PackageManifestStatus(a.(*PackageManifestStatus), b.(*operators.PackageManifestStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*operators.PackageManifestStatus)(nil), (*PackageManifestStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_operators_PackageManifestStatus_To_v1alpha1_PackageManifestStatus(a.(*operators.PackageManifestStatus), b.(*PackageManifestStatus), scope) + }); err != nil { + return err + } + return nil +} + +func autoConvert_v1alpha1_AppLink_To_operators_AppLink(in *AppLink, out *operators.AppLink, s conversion.Scope) error { + out.Name = in.Name + out.URL = in.URL + return nil +} + +// Convert_v1alpha1_AppLink_To_operators_AppLink is an autogenerated conversion function. +func Convert_v1alpha1_AppLink_To_operators_AppLink(in *AppLink, out *operators.AppLink, s conversion.Scope) error { + return autoConvert_v1alpha1_AppLink_To_operators_AppLink(in, out, s) +} + +func autoConvert_operators_AppLink_To_v1alpha1_AppLink(in *operators.AppLink, out *AppLink, s conversion.Scope) error { + out.Name = in.Name + out.URL = in.URL + return nil +} + +// Convert_operators_AppLink_To_v1alpha1_AppLink is an autogenerated conversion function. +func Convert_operators_AppLink_To_v1alpha1_AppLink(in *operators.AppLink, out *AppLink, s conversion.Scope) error { + return autoConvert_operators_AppLink_To_v1alpha1_AppLink(in, out, s) +} + +func autoConvert_v1alpha1_CSVDescription_To_operators_CSVDescription(in *CSVDescription, out *operators.CSVDescription, s conversion.Scope) error { + out.DisplayName = in.DisplayName + out.Icon = *(*[]operators.Icon)(unsafe.Pointer(&in.Icon)) + out.Version = in.Version + if err := Convert_v1alpha1_AppLink_To_operators_AppLink(&in.Provider, &out.Provider, s); err != nil { + return err + } + out.Annotations = *(*map[string]string)(unsafe.Pointer(&in.Annotations)) + out.LongDescription = in.LongDescription + out.InstallModes = *(*[]operatorsv1alpha1.InstallMode)(unsafe.Pointer(&in.InstallModes)) + return nil +} + +// Convert_v1alpha1_CSVDescription_To_operators_CSVDescription is an autogenerated conversion function. +func Convert_v1alpha1_CSVDescription_To_operators_CSVDescription(in *CSVDescription, out *operators.CSVDescription, s conversion.Scope) error { + return autoConvert_v1alpha1_CSVDescription_To_operators_CSVDescription(in, out, s) +} + +func autoConvert_operators_CSVDescription_To_v1alpha1_CSVDescription(in *operators.CSVDescription, out *CSVDescription, s conversion.Scope) error { + out.DisplayName = in.DisplayName + out.Icon = *(*[]Icon)(unsafe.Pointer(&in.Icon)) + out.Version = in.Version + if err := Convert_operators_AppLink_To_v1alpha1_AppLink(&in.Provider, &out.Provider, s); err != nil { + return err + } + out.Annotations = *(*map[string]string)(unsafe.Pointer(&in.Annotations)) + out.LongDescription = in.LongDescription + out.InstallModes = *(*[]operatorsv1alpha1.InstallMode)(unsafe.Pointer(&in.InstallModes)) + return nil +} + +// Convert_operators_CSVDescription_To_v1alpha1_CSVDescription is an autogenerated conversion function. +func Convert_operators_CSVDescription_To_v1alpha1_CSVDescription(in *operators.CSVDescription, out *CSVDescription, s conversion.Scope) error { + return autoConvert_operators_CSVDescription_To_v1alpha1_CSVDescription(in, out, s) +} + +func autoConvert_v1alpha1_Icon_To_operators_Icon(in *Icon, out *operators.Icon, s conversion.Scope) error { + out.Base64Data = in.Base64Data + out.Mediatype = in.Mediatype + return nil +} + +// Convert_v1alpha1_Icon_To_operators_Icon is an autogenerated conversion function. +func Convert_v1alpha1_Icon_To_operators_Icon(in *Icon, out *operators.Icon, s conversion.Scope) error { + return autoConvert_v1alpha1_Icon_To_operators_Icon(in, out, s) +} + +func autoConvert_operators_Icon_To_v1alpha1_Icon(in *operators.Icon, out *Icon, s conversion.Scope) error { + out.Base64Data = in.Base64Data + out.Mediatype = in.Mediatype + return nil +} + +// Convert_operators_Icon_To_v1alpha1_Icon is an autogenerated conversion function. +func Convert_operators_Icon_To_v1alpha1_Icon(in *operators.Icon, out *Icon, s conversion.Scope) error { + return autoConvert_operators_Icon_To_v1alpha1_Icon(in, out, s) +} + +func autoConvert_v1alpha1_PackageChannel_To_operators_PackageChannel(in *PackageChannel, out *operators.PackageChannel, s conversion.Scope) error { + out.Name = in.Name + out.CurrentCSV = in.CurrentCSV + if err := Convert_v1alpha1_CSVDescription_To_operators_CSVDescription(&in.CurrentCSVDesc, &out.CurrentCSVDesc, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha1_PackageChannel_To_operators_PackageChannel is an autogenerated conversion function. +func Convert_v1alpha1_PackageChannel_To_operators_PackageChannel(in *PackageChannel, out *operators.PackageChannel, s conversion.Scope) error { + return autoConvert_v1alpha1_PackageChannel_To_operators_PackageChannel(in, out, s) +} + +func autoConvert_operators_PackageChannel_To_v1alpha1_PackageChannel(in *operators.PackageChannel, out *PackageChannel, s conversion.Scope) error { + out.Name = in.Name + out.CurrentCSV = in.CurrentCSV + if err := Convert_operators_CSVDescription_To_v1alpha1_CSVDescription(&in.CurrentCSVDesc, &out.CurrentCSVDesc, s); err != nil { + return err + } + return nil +} + +// Convert_operators_PackageChannel_To_v1alpha1_PackageChannel is an autogenerated conversion function. +func Convert_operators_PackageChannel_To_v1alpha1_PackageChannel(in *operators.PackageChannel, out *PackageChannel, s conversion.Scope) error { + return autoConvert_operators_PackageChannel_To_v1alpha1_PackageChannel(in, out, s) +} + +func autoConvert_v1alpha1_PackageManifest_To_operators_PackageManifest(in *PackageManifest, out *operators.PackageManifest, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1alpha1_PackageManifestSpec_To_operators_PackageManifestSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v1alpha1_PackageManifestStatus_To_operators_PackageManifestStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha1_PackageManifest_To_operators_PackageManifest is an autogenerated conversion function. +func Convert_v1alpha1_PackageManifest_To_operators_PackageManifest(in *PackageManifest, out *operators.PackageManifest, s conversion.Scope) error { + return autoConvert_v1alpha1_PackageManifest_To_operators_PackageManifest(in, out, s) +} + +func autoConvert_operators_PackageManifest_To_v1alpha1_PackageManifest(in *operators.PackageManifest, out *PackageManifest, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_operators_PackageManifestSpec_To_v1alpha1_PackageManifestSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_operators_PackageManifestStatus_To_v1alpha1_PackageManifestStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +// Convert_operators_PackageManifest_To_v1alpha1_PackageManifest is an autogenerated conversion function. +func Convert_operators_PackageManifest_To_v1alpha1_PackageManifest(in *operators.PackageManifest, out *PackageManifest, s conversion.Scope) error { + return autoConvert_operators_PackageManifest_To_v1alpha1_PackageManifest(in, out, s) +} + +func autoConvert_v1alpha1_PackageManifestList_To_operators_PackageManifestList(in *PackageManifestList, out *operators.PackageManifestList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + out.Items = *(*[]operators.PackageManifest)(unsafe.Pointer(&in.Items)) + return nil +} + +// Convert_v1alpha1_PackageManifestList_To_operators_PackageManifestList is an autogenerated conversion function. +func Convert_v1alpha1_PackageManifestList_To_operators_PackageManifestList(in *PackageManifestList, out *operators.PackageManifestList, s conversion.Scope) error { + return autoConvert_v1alpha1_PackageManifestList_To_operators_PackageManifestList(in, out, s) +} + +func autoConvert_operators_PackageManifestList_To_v1alpha1_PackageManifestList(in *operators.PackageManifestList, out *PackageManifestList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + out.Items = *(*[]PackageManifest)(unsafe.Pointer(&in.Items)) + return nil +} + +// Convert_operators_PackageManifestList_To_v1alpha1_PackageManifestList is an autogenerated conversion function. +func Convert_operators_PackageManifestList_To_v1alpha1_PackageManifestList(in *operators.PackageManifestList, out *PackageManifestList, s conversion.Scope) error { + return autoConvert_operators_PackageManifestList_To_v1alpha1_PackageManifestList(in, out, s) +} + +func autoConvert_v1alpha1_PackageManifestSpec_To_operators_PackageManifestSpec(in *PackageManifestSpec, out *operators.PackageManifestSpec, s conversion.Scope) error { + return nil +} + +// Convert_v1alpha1_PackageManifestSpec_To_operators_PackageManifestSpec is an autogenerated conversion function. +func Convert_v1alpha1_PackageManifestSpec_To_operators_PackageManifestSpec(in *PackageManifestSpec, out *operators.PackageManifestSpec, s conversion.Scope) error { + return autoConvert_v1alpha1_PackageManifestSpec_To_operators_PackageManifestSpec(in, out, s) +} + +func autoConvert_operators_PackageManifestSpec_To_v1alpha1_PackageManifestSpec(in *operators.PackageManifestSpec, out *PackageManifestSpec, s conversion.Scope) error { + return nil +} + +// Convert_operators_PackageManifestSpec_To_v1alpha1_PackageManifestSpec is an autogenerated conversion function. +func Convert_operators_PackageManifestSpec_To_v1alpha1_PackageManifestSpec(in *operators.PackageManifestSpec, out *PackageManifestSpec, s conversion.Scope) error { + return autoConvert_operators_PackageManifestSpec_To_v1alpha1_PackageManifestSpec(in, out, s) +} + +func autoConvert_v1alpha1_PackageManifestStatus_To_operators_PackageManifestStatus(in *PackageManifestStatus, out *operators.PackageManifestStatus, s conversion.Scope) error { + out.CatalogSource = in.CatalogSource + out.CatalogSourceDisplayName = in.CatalogSourceDisplayName + out.CatalogSourcePublisher = in.CatalogSourcePublisher + out.CatalogSourceNamespace = in.CatalogSourceNamespace + if err := Convert_v1alpha1_AppLink_To_operators_AppLink(&in.Provider, &out.Provider, s); err != nil { + return err + } + out.PackageName = in.PackageName + out.Channels = *(*[]operators.PackageChannel)(unsafe.Pointer(&in.Channels)) + out.DefaultChannel = in.DefaultChannel + return nil +} + +// Convert_v1alpha1_PackageManifestStatus_To_operators_PackageManifestStatus is an autogenerated conversion function. +func Convert_v1alpha1_PackageManifestStatus_To_operators_PackageManifestStatus(in *PackageManifestStatus, out *operators.PackageManifestStatus, s conversion.Scope) error { + return autoConvert_v1alpha1_PackageManifestStatus_To_operators_PackageManifestStatus(in, out, s) +} + +func autoConvert_operators_PackageManifestStatus_To_v1alpha1_PackageManifestStatus(in *operators.PackageManifestStatus, out *PackageManifestStatus, s conversion.Scope) error { + out.CatalogSource = in.CatalogSource + out.CatalogSourceDisplayName = in.CatalogSourceDisplayName + out.CatalogSourcePublisher = in.CatalogSourcePublisher + out.CatalogSourceNamespace = in.CatalogSourceNamespace + if err := Convert_operators_AppLink_To_v1alpha1_AppLink(&in.Provider, &out.Provider, s); err != nil { + return err + } + out.PackageName = in.PackageName + out.Channels = *(*[]PackageChannel)(unsafe.Pointer(&in.Channels)) + out.DefaultChannel = in.DefaultChannel + return nil +} + +// Convert_operators_PackageManifestStatus_To_v1alpha1_PackageManifestStatus is an autogenerated conversion function. +func Convert_operators_PackageManifestStatus_To_v1alpha1_PackageManifestStatus(in *operators.PackageManifestStatus, out *PackageManifestStatus, s conversion.Scope) error { + return autoConvert_operators_PackageManifestStatus_To_v1alpha1_PackageManifestStatus(in, out, s) +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1/zz_generated.deepcopy.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 0000000000..72f3a59f85 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,211 @@ +// +build !ignore_autogenerated + +/* +Copyright 2019 Red Hat, 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 deepcopy-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + operatorsv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + 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 *AppLink) DeepCopyInto(out *AppLink) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppLink. +func (in *AppLink) DeepCopy() *AppLink { + if in == nil { + return nil + } + out := new(AppLink) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CSVDescription) DeepCopyInto(out *CSVDescription) { + *out = *in + if in.Icon != nil { + in, out := &in.Icon, &out.Icon + *out = make([]Icon, len(*in)) + copy(*out, *in) + } + out.Version = in.Version + out.Provider = in.Provider + 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 + } + } + if in.InstallModes != nil { + in, out := &in.InstallModes, &out.InstallModes + *out = make([]operatorsv1alpha1.InstallMode, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CSVDescription. +func (in *CSVDescription) DeepCopy() *CSVDescription { + if in == nil { + return nil + } + out := new(CSVDescription) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Icon) DeepCopyInto(out *Icon) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Icon. +func (in *Icon) DeepCopy() *Icon { + if in == nil { + return nil + } + out := new(Icon) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PackageChannel) DeepCopyInto(out *PackageChannel) { + *out = *in + in.CurrentCSVDesc.DeepCopyInto(&out.CurrentCSVDesc) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageChannel. +func (in *PackageChannel) DeepCopy() *PackageChannel { + if in == nil { + return nil + } + out := new(PackageChannel) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PackageManifest) DeepCopyInto(out *PackageManifest) { + *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 PackageManifest. +func (in *PackageManifest) DeepCopy() *PackageManifest { + if in == nil { + return nil + } + out := new(PackageManifest) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PackageManifest) 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 *PackageManifestList) DeepCopyInto(out *PackageManifestList) { + *out = *in + out.TypeMeta = in.TypeMeta + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]PackageManifest, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageManifestList. +func (in *PackageManifestList) DeepCopy() *PackageManifestList { + if in == nil { + return nil + } + out := new(PackageManifestList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PackageManifestList) 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 *PackageManifestSpec) DeepCopyInto(out *PackageManifestSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageManifestSpec. +func (in *PackageManifestSpec) DeepCopy() *PackageManifestSpec { + if in == nil { + return nil + } + out := new(PackageManifestSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PackageManifestStatus) DeepCopyInto(out *PackageManifestStatus) { + *out = *in + out.Provider = in.Provider + if in.Channels != nil { + in, out := &in.Channels, &out.Channels + *out = make([]PackageChannel, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageManifestStatus. +func (in *PackageManifestStatus) DeepCopy() *PackageManifestStatus { + if in == nil { + return nil + } + out := new(PackageManifestStatus) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1/zz_generated.defaults.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1/zz_generated.defaults.go new file mode 100644 index 0000000000..d43ad5fdc8 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1/zz_generated.defaults.go @@ -0,0 +1,32 @@ +// +build !ignore_autogenerated + +/* +Copyright 2019 Red Hat, 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 defaulter-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// RegisterDefaults adds defaulters functions to the given scheme. +// Public to allow building arbitrary schemes. +// All generated defaulters are covering - they call all nested defaulters. +func RegisterDefaults(scheme *runtime.Scheme) error { + return nil +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/doc.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/doc.go new file mode 100644 index 0000000000..7b272ed514 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/doc.go @@ -0,0 +1 @@ +package apis diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/generated/openapi/zz_generated.openapi.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/openapi/zz_generated.openapi.go similarity index 70% rename from vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/generated/openapi/zz_generated.openapi.go rename to vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/openapi/zz_generated.openapi.go index c6b5d2985c..a2ef5f6718 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/generated/openapi/zz_generated.openapi.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/openapi/zz_generated.openapi.go @@ -1,7 +1,7 @@ // +build !ignore_autogenerated /* -Copyright 2018 CoreOS, Inc. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -30,56 +30,429 @@ import ( func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition { return map[string]common.OpenAPIDefinition{ - "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1.AppLink": schema_package_server_apis_packagemanifest_v1alpha1_AppLink(ref), - "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1.CSVDescription": schema_package_server_apis_packagemanifest_v1alpha1_CSVDescription(ref), - "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1.Icon": schema_package_server_apis_packagemanifest_v1alpha1_Icon(ref), - "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1.PackageChannel": schema_package_server_apis_packagemanifest_v1alpha1_PackageChannel(ref), - "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1.PackageManifest": schema_package_server_apis_packagemanifest_v1alpha1_PackageManifest(ref), - "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1.PackageManifestList": schema_package_server_apis_packagemanifest_v1alpha1_PackageManifestList(ref), - "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1.PackageManifestSpec": schema_package_server_apis_packagemanifest_v1alpha1_PackageManifestSpec(ref), - "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1.PackageManifestStatus": schema_package_server_apis_packagemanifest_v1alpha1_PackageManifestStatus(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.APIGroup": schema_pkg_apis_meta_v1_APIGroup(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.APIGroupList": schema_pkg_apis_meta_v1_APIGroupList(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.APIResource": schema_pkg_apis_meta_v1_APIResource(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.APIResourceList": schema_pkg_apis_meta_v1_APIResourceList(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.APIVersions": schema_pkg_apis_meta_v1_APIVersions(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.DeleteOptions": schema_pkg_apis_meta_v1_DeleteOptions(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.Duration": schema_pkg_apis_meta_v1_Duration(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.ExportOptions": schema_pkg_apis_meta_v1_ExportOptions(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.GetOptions": schema_pkg_apis_meta_v1_GetOptions(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.GroupKind": schema_pkg_apis_meta_v1_GroupKind(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.GroupResource": schema_pkg_apis_meta_v1_GroupResource(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.GroupVersion": schema_pkg_apis_meta_v1_GroupVersion(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.GroupVersionForDiscovery": schema_pkg_apis_meta_v1_GroupVersionForDiscovery(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.GroupVersionKind": schema_pkg_apis_meta_v1_GroupVersionKind(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.GroupVersionResource": schema_pkg_apis_meta_v1_GroupVersionResource(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.Initializer": schema_pkg_apis_meta_v1_Initializer(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.Initializers": schema_pkg_apis_meta_v1_Initializers(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.InternalEvent": schema_pkg_apis_meta_v1_InternalEvent(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector": schema_pkg_apis_meta_v1_LabelSelector(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelectorRequirement": schema_pkg_apis_meta_v1_LabelSelectorRequirement(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.List": schema_pkg_apis_meta_v1_List(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta": schema_pkg_apis_meta_v1_ListMeta(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.ListOptions": schema_pkg_apis_meta_v1_ListOptions(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.MicroTime": schema_pkg_apis_meta_v1_MicroTime(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta": schema_pkg_apis_meta_v1_ObjectMeta(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.OwnerReference": schema_pkg_apis_meta_v1_OwnerReference(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.Patch": schema_pkg_apis_meta_v1_Patch(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.Preconditions": schema_pkg_apis_meta_v1_Preconditions(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.RootPaths": schema_pkg_apis_meta_v1_RootPaths(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.ServerAddressByClientCIDR": schema_pkg_apis_meta_v1_ServerAddressByClientCIDR(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.Status": schema_pkg_apis_meta_v1_Status(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.StatusCause": schema_pkg_apis_meta_v1_StatusCause(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.StatusDetails": schema_pkg_apis_meta_v1_StatusDetails(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.Time": schema_pkg_apis_meta_v1_Time(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.Timestamp": schema_pkg_apis_meta_v1_Timestamp(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.TypeMeta": schema_pkg_apis_meta_v1_TypeMeta(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.WatchEvent": schema_pkg_apis_meta_v1_WatchEvent(ref), - "k8s.io/apimachinery/pkg/version.Info": schema_k8sio_apimachinery_pkg_version_Info(ref), + "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1.InstallMode": schema_api_apis_operators_v1alpha1_InstallMode(ref), + "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1.AppLink": schema_package_server_apis_apps_v1alpha1_AppLink(ref), + "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1.CSVDescription": schema_package_server_apis_apps_v1alpha1_CSVDescription(ref), + "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1.Icon": schema_package_server_apis_apps_v1alpha1_Icon(ref), + "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1.PackageChannel": schema_package_server_apis_apps_v1alpha1_PackageChannel(ref), + "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1.PackageManifest": schema_package_server_apis_apps_v1alpha1_PackageManifest(ref), + "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1.PackageManifestList": schema_package_server_apis_apps_v1alpha1_PackageManifestList(ref), + "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1.PackageManifestSpec": schema_package_server_apis_apps_v1alpha1_PackageManifestSpec(ref), + "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1.PackageManifestStatus": schema_package_server_apis_apps_v1alpha1_PackageManifestStatus(ref), + "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1.AppLink": schema_package_server_apis_operators_v1_AppLink(ref), + "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1.CSVDescription": schema_package_server_apis_operators_v1_CSVDescription(ref), + "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1.Icon": schema_package_server_apis_operators_v1_Icon(ref), + "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1.PackageChannel": schema_package_server_apis_operators_v1_PackageChannel(ref), + "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1.PackageManifest": schema_package_server_apis_operators_v1_PackageManifest(ref), + "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1.PackageManifestList": schema_package_server_apis_operators_v1_PackageManifestList(ref), + "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1.PackageManifestSpec": schema_package_server_apis_operators_v1_PackageManifestSpec(ref), + "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1.PackageManifestStatus": schema_package_server_apis_operators_v1_PackageManifestStatus(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.APIGroup": schema_pkg_apis_meta_v1_APIGroup(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.APIGroupList": schema_pkg_apis_meta_v1_APIGroupList(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.APIResource": schema_pkg_apis_meta_v1_APIResource(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.APIResourceList": schema_pkg_apis_meta_v1_APIResourceList(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.APIVersions": schema_pkg_apis_meta_v1_APIVersions(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.CreateOptions": schema_pkg_apis_meta_v1_CreateOptions(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.DeleteOptions": schema_pkg_apis_meta_v1_DeleteOptions(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.Duration": schema_pkg_apis_meta_v1_Duration(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.ExportOptions": schema_pkg_apis_meta_v1_ExportOptions(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.GetOptions": schema_pkg_apis_meta_v1_GetOptions(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.GroupKind": schema_pkg_apis_meta_v1_GroupKind(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.GroupResource": schema_pkg_apis_meta_v1_GroupResource(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.GroupVersion": schema_pkg_apis_meta_v1_GroupVersion(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.GroupVersionForDiscovery": schema_pkg_apis_meta_v1_GroupVersionForDiscovery(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.GroupVersionKind": schema_pkg_apis_meta_v1_GroupVersionKind(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.GroupVersionResource": schema_pkg_apis_meta_v1_GroupVersionResource(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.Initializer": schema_pkg_apis_meta_v1_Initializer(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.Initializers": schema_pkg_apis_meta_v1_Initializers(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.InternalEvent": schema_pkg_apis_meta_v1_InternalEvent(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector": schema_pkg_apis_meta_v1_LabelSelector(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelectorRequirement": schema_pkg_apis_meta_v1_LabelSelectorRequirement(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.List": schema_pkg_apis_meta_v1_List(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta": schema_pkg_apis_meta_v1_ListMeta(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.ListOptions": schema_pkg_apis_meta_v1_ListOptions(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.MicroTime": schema_pkg_apis_meta_v1_MicroTime(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta": schema_pkg_apis_meta_v1_ObjectMeta(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.OwnerReference": schema_pkg_apis_meta_v1_OwnerReference(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.Patch": schema_pkg_apis_meta_v1_Patch(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.Preconditions": schema_pkg_apis_meta_v1_Preconditions(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.RootPaths": schema_pkg_apis_meta_v1_RootPaths(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.ServerAddressByClientCIDR": schema_pkg_apis_meta_v1_ServerAddressByClientCIDR(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.Status": schema_pkg_apis_meta_v1_Status(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.StatusCause": schema_pkg_apis_meta_v1_StatusCause(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.StatusDetails": schema_pkg_apis_meta_v1_StatusDetails(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.Time": schema_pkg_apis_meta_v1_Time(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.Timestamp": schema_pkg_apis_meta_v1_Timestamp(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.TypeMeta": schema_pkg_apis_meta_v1_TypeMeta(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.UpdateOptions": schema_pkg_apis_meta_v1_UpdateOptions(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.WatchEvent": schema_pkg_apis_meta_v1_WatchEvent(ref), + "k8s.io/apimachinery/pkg/runtime.RawExtension": schema_k8sio_apimachinery_pkg_runtime_RawExtension(ref), + "k8s.io/apimachinery/pkg/runtime.TypeMeta": schema_k8sio_apimachinery_pkg_runtime_TypeMeta(ref), + "k8s.io/apimachinery/pkg/runtime.Unknown": schema_k8sio_apimachinery_pkg_runtime_Unknown(ref), + "k8s.io/apimachinery/pkg/version.Info": schema_k8sio_apimachinery_pkg_version_Info(ref), } } -func schema_package_server_apis_packagemanifest_v1alpha1_AppLink(ref common.ReferenceCallback) common.OpenAPIDefinition { +func schema_api_apis_operators_v1alpha1_InstallMode(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "InstallMode associates an InstallModeType with a flag representing if the CSV supports it", + Properties: map[string]spec.Schema{ + "type": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "supported": { + SchemaProps: spec.SchemaProps{ + Type: []string{"boolean"}, + Format: "", + }, + }, + }, + Required: []string{"type", "supported"}, + }, + }, + Dependencies: []string{}, + } +} + +func schema_package_server_apis_apps_v1alpha1_AppLink(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "AppLink defines a link to an application", + Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "url": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + Dependencies: []string{}, + } +} + +func schema_package_server_apis_apps_v1alpha1_CSVDescription(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "CSVDescription defines a description of a CSV", + Properties: map[string]spec.Schema{ + "displayName": { + SchemaProps: spec.SchemaProps{ + Description: "DisplayName is the CSV's display name", + Type: []string{"string"}, + Format: "", + }, + }, + "icon": { + SchemaProps: spec.SchemaProps{ + Description: "Icon is the CSV's base64 encoded icon", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1.Icon"), + }, + }, + }, + }, + }, + "provider": { + SchemaProps: spec.SchemaProps{ + Description: "Provider is the CSV's provider", + Ref: ref("github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1.AppLink"), + }, + }, + "annotations": { + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + AdditionalProperties: &spec.SchemaOrBool{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + "description": { + SchemaProps: spec.SchemaProps{ + Description: "LongDescription is the CSV's description", + Type: []string{"string"}, + Format: "", + }, + }, + "installModes": { + SchemaProps: spec.SchemaProps{ + Description: "InstallModes specify supported installation types", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1.InstallMode"), + }, + }, + }, + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1.InstallMode", "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1.AppLink", "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1.Icon"}, + } +} + +func schema_package_server_apis_apps_v1alpha1_Icon(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Icon defines a base64 encoded icon and media type", + Properties: map[string]spec.Schema{ + "base64data": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "mediatype": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + Dependencies: []string{}, + } +} + +func schema_package_server_apis_apps_v1alpha1_PackageChannel(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "PackageChannel defines a single channel under a package, pointing to a version of that package.", + Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Description: "Name is the name of the channel, e.g. `alpha` or `stable`", + Type: []string{"string"}, + Format: "", + }, + }, + "currentCSV": { + SchemaProps: spec.SchemaProps{ + Description: "CurrentCSV defines a reference to the CSV holding the version of this package currently for the channel.", + Type: []string{"string"}, + Format: "", + }, + }, + "currentCSVDesc": { + SchemaProps: spec.SchemaProps{ + Description: "CurrentCSVSpec holds the spec of the current CSV", + Ref: ref("github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1.CSVDescription"), + }, + }, + }, + Required: []string{"name", "currentCSV"}, + }, + }, + Dependencies: []string{ + "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1.CSVDescription"}, + } +} + +func schema_package_server_apis_apps_v1alpha1_PackageManifest(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "PackageManifest holds information about a package, which is a reference to one (or more) channels under a single package.", + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + 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/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + 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/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1.PackageManifestSpec"), + }, + }, + "status": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1.PackageManifestStatus"), + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1.PackageManifestSpec", "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1.PackageManifestStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + } +} + +func schema_package_server_apis_apps_v1alpha1_PackageManifestList(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "PackageManifestList is a list of PackageManifest objects.", + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + 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/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + 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/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), + }, + }, + "items": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1.PackageManifest"), + }, + }, + }, + }, + }, + }, + Required: []string{"items"}, + }, + }, + Dependencies: []string{ + "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1.PackageManifest", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, + } +} + +func schema_package_server_apis_apps_v1alpha1_PackageManifestSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "PackageManifestSpec defines the desired state of PackageManifest", + Properties: map[string]spec.Schema{}, + }, + }, + Dependencies: []string{}, + } +} + +func schema_package_server_apis_apps_v1alpha1_PackageManifestStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "PackageManifestStatus represents the current status of the PackageManifest", + Properties: map[string]spec.Schema{ + "catalogSource": { + SchemaProps: spec.SchemaProps{ + Description: "CatalogSource is the name of the CatalogSource this package belongs to", + Type: []string{"string"}, + Format: "", + }, + }, + "catalogSourceDisplayName": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "catalogSourcePublisher": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "catalogSourceNamespace": { + SchemaProps: spec.SchemaProps{ + Description: "\n CatalogSourceNamespace is the namespace of the owning CatalogSource", + Type: []string{"string"}, + Format: "", + }, + }, + "provider": { + SchemaProps: spec.SchemaProps{ + Description: "Provider is the provider of the PackageManifest's default CSV", + Ref: ref("github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1.AppLink"), + }, + }, + "packageName": { + SchemaProps: spec.SchemaProps{ + Description: "PackageName is the name of the overall package, ala `etcd`.", + Type: []string{"string"}, + Format: "", + }, + }, + "channels": { + SchemaProps: spec.SchemaProps{ + Description: "Channels are the declared channels for the package, ala `stable` or `alpha`.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1.PackageChannel"), + }, + }, + }, + }, + }, + "defaultChannel": { + SchemaProps: spec.SchemaProps{ + Description: "DefaultChannel is, if specified, the name of the default channel for the package. The default channel will be installed if no other channel is explicitly given. If the package has a single channel, then that channel is implicitly the default.", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"catalogSource", "catalogSourceDisplayName", "catalogSourcePublisher", "catalogSourceNamespace", "packageName", "channels", "defaultChannel"}, + }, + }, + Dependencies: []string{ + "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1.AppLink", "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1.PackageChannel"}, + } +} + +func schema_package_server_apis_operators_v1_AppLink(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ @@ -104,7 +477,7 @@ func schema_package_server_apis_packagemanifest_v1alpha1_AppLink(ref common.Refe } } -func schema_package_server_apis_packagemanifest_v1alpha1_CSVDescription(ref common.ReferenceCallback) common.OpenAPIDefinition { +func schema_package_server_apis_operators_v1_CSVDescription(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ @@ -124,7 +497,7 @@ func schema_package_server_apis_packagemanifest_v1alpha1_CSVDescription(ref comm Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1.Icon"), + Ref: ref("github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1.Icon"), }, }, }, @@ -133,18 +506,51 @@ func schema_package_server_apis_packagemanifest_v1alpha1_CSVDescription(ref comm "provider": { SchemaProps: spec.SchemaProps{ Description: "Provider is the CSV's provider", - Ref: ref("github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1.AppLink"), + Ref: ref("github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1.AppLink"), + }, + }, + "annotations": { + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + AdditionalProperties: &spec.SchemaOrBool{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + "description": { + SchemaProps: spec.SchemaProps{ + Description: "LongDescription is the CSV's description", + Type: []string{"string"}, + Format: "", + }, + }, + "installModes": { + SchemaProps: spec.SchemaProps{ + Description: "InstallModes specify supported installation types", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1.InstallMode"), + }, + }, + }, }, }, }, }, }, Dependencies: []string{ - "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1.AppLink", "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1.Icon"}, + "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1.InstallMode", "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1.AppLink", "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1.Icon"}, } } -func schema_package_server_apis_packagemanifest_v1alpha1_Icon(ref common.ReferenceCallback) common.OpenAPIDefinition { +func schema_package_server_apis_operators_v1_Icon(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ @@ -169,7 +575,7 @@ func schema_package_server_apis_packagemanifest_v1alpha1_Icon(ref common.Referen } } -func schema_package_server_apis_packagemanifest_v1alpha1_PackageChannel(ref common.ReferenceCallback) common.OpenAPIDefinition { +func schema_package_server_apis_operators_v1_PackageChannel(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ @@ -184,7 +590,7 @@ func schema_package_server_apis_packagemanifest_v1alpha1_PackageChannel(ref comm }, "currentCSV": { SchemaProps: spec.SchemaProps{ - Description: "CurrentCSVName defines a reference to the CSV holding the version of this package currently for the channel.", + Description: "CurrentCSV defines a reference to the CSV holding the version of this package currently for the channel.", Type: []string{"string"}, Format: "", }, @@ -192,7 +598,7 @@ func schema_package_server_apis_packagemanifest_v1alpha1_PackageChannel(ref comm "currentCSVDesc": { SchemaProps: spec.SchemaProps{ Description: "CurrentCSVSpec holds the spec of the current CSV", - Ref: ref("github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1.CSVDescription"), + Ref: ref("github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1.CSVDescription"), }, }, }, @@ -200,11 +606,11 @@ func schema_package_server_apis_packagemanifest_v1alpha1_PackageChannel(ref comm }, }, Dependencies: []string{ - "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1.CSVDescription"}, + "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1.CSVDescription"}, } } -func schema_package_server_apis_packagemanifest_v1alpha1_PackageManifest(ref common.ReferenceCallback) common.OpenAPIDefinition { +func schema_package_server_apis_operators_v1_PackageManifest(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ @@ -231,23 +637,23 @@ func schema_package_server_apis_packagemanifest_v1alpha1_PackageManifest(ref com }, "spec": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1.PackageManifestSpec"), + Ref: ref("github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1.PackageManifestSpec"), }, }, "status": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1.PackageManifestStatus"), + Ref: ref("github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1.PackageManifestStatus"), }, }, }, }, }, Dependencies: []string{ - "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1.PackageManifestSpec", "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1.PackageManifestStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1.PackageManifestSpec", "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1.PackageManifestStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, } } -func schema_package_server_apis_packagemanifest_v1alpha1_PackageManifestList(ref common.ReferenceCallback) common.OpenAPIDefinition { +func schema_package_server_apis_operators_v1_PackageManifestList(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ @@ -278,7 +684,7 @@ func schema_package_server_apis_packagemanifest_v1alpha1_PackageManifestList(ref Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1.PackageManifest"), + Ref: ref("github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1.PackageManifest"), }, }, }, @@ -289,11 +695,11 @@ func schema_package_server_apis_packagemanifest_v1alpha1_PackageManifestList(ref }, }, Dependencies: []string{ - "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1.PackageManifest", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, + "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1.PackageManifest", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, } } -func schema_package_server_apis_packagemanifest_v1alpha1_PackageManifestSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { +func schema_package_server_apis_operators_v1_PackageManifestSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ @@ -305,7 +711,7 @@ func schema_package_server_apis_packagemanifest_v1alpha1_PackageManifestSpec(ref } } -func schema_package_server_apis_packagemanifest_v1alpha1_PackageManifestStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { +func schema_package_server_apis_operators_v1_PackageManifestStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ @@ -313,11 +719,23 @@ func schema_package_server_apis_packagemanifest_v1alpha1_PackageManifestStatus(r Properties: map[string]spec.Schema{ "catalogSource": { SchemaProps: spec.SchemaProps{ - Description: "CatalogSourceName is the name of the CatalogSource this package belongs to", + Description: "CatalogSource is the name of the CatalogSource this package belongs to", Type: []string{"string"}, Format: "", }, }, + "catalogSourceDisplayName": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "catalogSourcePublisher": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, "catalogSourceNamespace": { SchemaProps: spec.SchemaProps{ Description: "\n CatalogSourceNamespace is the namespace of the owning CatalogSource", @@ -328,7 +746,7 @@ func schema_package_server_apis_packagemanifest_v1alpha1_PackageManifestStatus(r "provider": { SchemaProps: spec.SchemaProps{ Description: "Provider is the provider of the PackageManifest's default CSV", - Ref: ref("github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1.AppLink"), + Ref: ref("github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1.AppLink"), }, }, "packageName": { @@ -345,7 +763,7 @@ func schema_package_server_apis_packagemanifest_v1alpha1_PackageManifestStatus(r Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1.PackageChannel"), + Ref: ref("github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1.PackageChannel"), }, }, }, @@ -353,17 +771,17 @@ func schema_package_server_apis_packagemanifest_v1alpha1_PackageManifestStatus(r }, "defaultChannel": { SchemaProps: spec.SchemaProps{ - Description: "DefaultChannelName is, if specified, the name of the default channel for the package. The default channel will be installed if no other channel is explicitly given. If the package has a single channel, then that channel is implicitly the default.", + Description: "DefaultChannel is, if specified, the name of the default channel for the package. The default channel will be installed if no other channel is explicitly given. If the package has a single channel, then that channel is implicitly the default.", Type: []string{"string"}, Format: "", }, }, }, - Required: []string{"catalogSource", "catalogSourceNamespace", "packageName", "channels", "defaultChannel"}, + Required: []string{"catalogSource", "catalogSourceDisplayName", "catalogSourcePublisher", "catalogSourceNamespace", "packageName", "channels", "defaultChannel"}, }, }, Dependencies: []string{ - "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1.AppLink", "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1.PackageChannel"}, + "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1.AppLink", "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1.PackageChannel"}, } } @@ -680,6 +1098,54 @@ func schema_pkg_apis_meta_v1_APIVersions(ref common.ReferenceCallback) common.Op } } +func schema_pkg_apis_meta_v1_CreateOptions(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "CreateOptions may be provided when creating an API object.", + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + 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/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + 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/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", + }, + }, + "dryRun": { + SchemaProps: spec.SchemaProps{ + Description: "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + "includeUninitialized": { + SchemaProps: spec.SchemaProps{ + Description: "If IncludeUninitialized is specified, the object may be returned without completing initialization.", + Type: []string{"boolean"}, + Format: "", + }, + }, + }, + }, + }, + Dependencies: []string{}, + } +} + func schema_pkg_apis_meta_v1_DeleteOptions(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -727,6 +1193,20 @@ func schema_pkg_apis_meta_v1_DeleteOptions(ref common.ReferenceCallback) common. Format: "", }, }, + "dryRun": { + SchemaProps: spec.SchemaProps{ + Description: "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, }, }, }, @@ -1255,7 +1735,7 @@ func schema_pkg_apis_meta_v1_ListMeta(ref common.ReferenceCallback) common.OpenA }, "continue": { SchemaProps: spec.SchemaProps{ - Description: "continue may be set if the user set a limit on the number of items returned, and indicates that the server has more data available. The value is opaque and may be used to issue another request to the endpoint that served this list to retrieve the next set of available objects. Continuing a list may not be possible if the server configuration has changed or more than a few minutes have passed. The resourceVersion field returned when using this continue value will be identical to the value in the first response.", + Description: "continue may be set if the user set a limit on the number of items returned, and indicates that the server has more data available. The value is opaque and may be used to issue another request to the endpoint that served this list to retrieve the next set of available objects. Continuing a consistent list may not be possible if the server configuration has changed or more than a few minutes have passed. The resourceVersion field returned when using this continue value will be identical to the value in the first response, unless you have received this token from an error message.", Type: []string{"string"}, Format: "", }, @@ -1338,7 +1818,7 @@ func schema_pkg_apis_meta_v1_ListOptions(ref common.ReferenceCallback) common.Op }, "continue": { SchemaProps: spec.SchemaProps{ - Description: "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server the server will respond with a 410 ResourceExpired error indicating the client must restart their list without the continue field. This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + Description: "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", Type: []string{"string"}, Format: "", }, @@ -1898,6 +2378,47 @@ func schema_pkg_apis_meta_v1_TypeMeta(ref common.ReferenceCallback) common.OpenA } } +func schema_pkg_apis_meta_v1_UpdateOptions(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "UpdateOptions may be provided when updating an API object.", + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + 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/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + 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/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", + }, + }, + "dryRun": { + SchemaProps: spec.SchemaProps{ + Description: "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + }, + }, + }, + Dependencies: []string{}, + } +} + func schema_pkg_apis_meta_v1_WatchEvent(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -1925,6 +2446,99 @@ func schema_pkg_apis_meta_v1_WatchEvent(ref common.ReferenceCallback) common.Ope } } +func schema_k8sio_apimachinery_pkg_runtime_RawExtension(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "RawExtension is used to hold extensions in external versions.\n\nTo use this, make a field which has RawExtension as its type in your external, versioned struct, and Object in your internal struct. You also need to register your various plugin types.\n\n// Internal package: type MyAPIObject struct {\n\truntime.TypeMeta `json:\",inline\"`\n\tMyPlugin runtime.Object `json:\"myPlugin\"`\n} type PluginA struct {\n\tAOption string `json:\"aOption\"`\n}\n\n// External package: type MyAPIObject struct {\n\truntime.TypeMeta `json:\",inline\"`\n\tMyPlugin runtime.RawExtension `json:\"myPlugin\"`\n} type PluginA struct {\n\tAOption string `json:\"aOption\"`\n}\n\n// On the wire, the JSON will look something like this: {\n\t\"kind\":\"MyAPIObject\",\n\t\"apiVersion\":\"v1\",\n\t\"myPlugin\": {\n\t\t\"kind\":\"PluginA\",\n\t\t\"aOption\":\"foo\",\n\t},\n}\n\nSo what happens? Decode first uses json or yaml to unmarshal the serialized data into your external MyAPIObject. That causes the raw JSON to be stored, but not unpacked. The next step is to copy (using pkg/conversion) into the internal struct. The runtime package's DefaultScheme has conversion functions installed which will unpack the JSON stored in RawExtension, turning it into the correct object type, and storing it in the Object. (TODO: In the case where the object is of an unknown type, a runtime.Unknown object will be created and stored.)", + Properties: map[string]spec.Schema{ + "Raw": { + SchemaProps: spec.SchemaProps{ + Description: "Raw is the underlying serialization of this object.", + Type: []string{"string"}, + Format: "byte", + }, + }, + }, + Required: []string{"Raw"}, + }, + }, + Dependencies: []string{}, + } +} + +func schema_k8sio_apimachinery_pkg_runtime_TypeMeta(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "TypeMeta is shared by all top level objects. The proper way to use it is to inline it in your type, like this: type MyAwesomeAPIObject struct {\n runtime.TypeMeta `json:\",inline\"`\n ... // other fields\n} func (obj *MyAwesomeAPIObject) SetGroupVersionKind(gvk *metav1.GroupVersionKind) { metav1.UpdateTypeMeta(obj,gvk) }; GroupVersionKind() *GroupVersionKind\n\nTypeMeta is provided here for convenience. You may use it directly from this package or define your own with the same fields.", + Properties: map[string]spec.Schema{ + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "kind": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + Dependencies: []string{}, + } +} + +func schema_k8sio_apimachinery_pkg_runtime_Unknown(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Unknown allows api objects with unknown types to be passed-through. This can be used to deal with the API objects from a plug-in. Unknown objects still have functioning TypeMeta features-- kind, version, etc. metadata and field mutatation.", + Properties: map[string]spec.Schema{ + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "kind": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "Raw": { + SchemaProps: spec.SchemaProps{ + Description: "Raw will hold the complete serialized object which couldn't be matched with a registered type. Most likely, nothing should be done with this except for passing it through the system.", + Type: []string{"string"}, + Format: "byte", + }, + }, + "ContentEncoding": { + SchemaProps: spec.SchemaProps{ + Description: "ContentEncoding is encoding used to encode 'Raw' data. Unspecified means no encoding.", + Type: []string{"string"}, + Format: "", + }, + }, + "ContentType": { + SchemaProps: spec.SchemaProps{ + Description: "ContentType is serialization method used to serialize 'Raw'. Unspecified means ContentTypeJSON.", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"Raw", "ContentEncoding", "ContentType"}, + }, + }, + Dependencies: []string{}, + } +} + func schema_k8sio_apimachinery_pkg_version_Info(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/doc.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/doc.go new file mode 100644 index 0000000000..b5f420c289 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/doc.go @@ -0,0 +1,5 @@ +// +k8s:deepcopy-gen=package + +// Package operators is the internal version of the API. +// +groupName=operators.coreos.com +package operators diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/install/install.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/install/install.go new file mode 100644 index 0000000000..15e44fda1d --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/install/install.go @@ -0,0 +1,16 @@ +package install + +import ( + "k8s.io/apimachinery/pkg/runtime" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + + "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators" + v1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1" +) + +// Install registers API groups and adds types to a scheme. +func Install(scheme *runtime.Scheme) { + utilruntime.Must(operators.AddToScheme(scheme)) + utilruntime.Must(v1.AddToScheme(scheme)) + utilruntime.Must(scheme.SetVersionPriority(v1.SchemeGroupVersion)) +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/packagemanifest.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/packagemanifest.go new file mode 100644 index 0000000000..9ec08911cd --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/packagemanifest.go @@ -0,0 +1,32 @@ +package operators + +import operatorsv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + +// CreateCSVDescription creates a CSVDescription from a given CSV +func CreateCSVDescription(csv *operatorsv1alpha1.ClusterServiceVersion) CSVDescription { + desc := CSVDescription{ + DisplayName: csv.Spec.DisplayName, + Version: csv.Spec.Version, + Provider: AppLink{ + Name: csv.Spec.Provider.Name, + URL: csv.Spec.Provider.URL, + }, + Annotations: csv.GetAnnotations(), + LongDescription: csv.Spec.Description, + InstallModes: csv.Spec.InstallModes, + } + + icons := make([]Icon, len(csv.Spec.Icon)) + for i, icon := range csv.Spec.Icon { + icons[i] = Icon{ + Base64Data: icon.Data, + Mediatype: icon.MediaType, + } + } + + if len(icons) > 0 { + desc.Icon = icons + } + + return desc +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/packagemanifest_types.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/packagemanifest_types.go new file mode 100644 index 0000000000..aec1ef3745 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/packagemanifest_types.go @@ -0,0 +1,123 @@ +package operators + +import ( + "github.com/coreos/go-semver/semver" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + operatorv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" +) + +// PackageManifestList is a list of PackageManifest objects. +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type PackageManifestList struct { + metav1.TypeMeta + metav1.ListMeta + + Items []PackageManifest +} + +// PackageManifest holds information about a package, which is a reference to one (or more) +// channels under a single package. +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type PackageManifest struct { + metav1.TypeMeta + metav1.ObjectMeta + + Spec PackageManifestSpec + Status PackageManifestStatus +} + +// PackageManifestSpec defines the desired state of PackageManifest +type PackageManifestSpec struct{} + +// PackageManifestStatus represents the current status of the PackageManifest +type PackageManifestStatus struct { + // CatalogSource is the name of the CatalogSource this package belongs to + CatalogSource string + CatalogSourceDisplayName string + CatalogSourcePublisher string + + // CatalogSourceNamespace is the namespace of the owning CatalogSource + CatalogSourceNamespace string + + // Provider is the provider of the PackageManifest's default CSV + Provider AppLink + + // PackageName is the name of the overall package, ala . + PackageName string + + // Channels are the declared channels for the package, ala . + Channels []PackageChannel + + // DefaultChannel is, if specified, the name of the default channel for the package. The + // default channel will be installed if no other channel is explicitly given. If the package + // has a single channel, then that channel is implicitly the default. + DefaultChannel string +} + +// GetDefaultChannel gets the default channel or returns the only one if there's only one. returns empty string if it +// can't determine the default +func (m PackageManifest) GetDefaultChannel() string { + if m.Status.DefaultChannel != "" { + return m.Status.DefaultChannel + } + if len(m.Status.Channels) == 1 { + return m.Status.Channels[0].Name + } + return "" +} + +// PackageChannel defines a single channel under a package, pointing to a version of that +// package. +type PackageChannel struct { + // Name is the name of the channel, e.g. + Name string + + // CurrentCSV defines a reference to the CSV holding the version of this package currently + // for the channel. + CurrentCSV string + + // CurrentCSVSpec holds the spec of the current CSV + CurrentCSVDesc CSVDescription +} + +// CSVDescription defines a description of a CSV +type CSVDescription struct { + // DisplayName is the CSV's display name + DisplayName string + + // Icon is the CSV's base64 encoded icon + Icon []Icon + + // Version is the CSV's semantic version + // +k8s:openapi-gen=false + Version semver.Version + + // Provider is the CSV's provider + Provider AppLink + Annotations map[string]string + + // LongDescription is the CSV's description + LongDescription string + + // InstallModes specify supported installation types + InstallModes []operatorv1alpha1.InstallMode +} + +// AppLink defines a link to an application +type AppLink struct { + Name string + URL string +} + +// Icon defines a base64 encoded icon and media type +type Icon struct { + Base64Data string + Mediatype string +} + +// IsDefaultChannel returns true if the PackageChannel is the default for the PackageManifest +func (pc PackageChannel) IsDefaultChannel(pm PackageManifest) bool { + return pc.Name == pm.Status.DefaultChannel || len(pm.Status.Channels) == 1 +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/register.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/register.go new file mode 100644 index 0000000000..d8e29880a8 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/register.go @@ -0,0 +1,36 @@ +package operators + +import ( + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +var ( + Group = "packages.operators.coreos.com" + + // SchemeGroupVersion is the GroupVersion used to register this object + SchemeGroupVersion = schema.GroupVersion{Group: Group, Version: runtime.APIVersionInternal} + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + AddToScheme = SchemeBuilder.AddToScheme +) + +// Kind takes an unqualified kind and returns the group-qualified kind. +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns the group-qualified resource. +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +// addKnownTypes adds the set of types defined in this package to the supplied scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + // Add types for each GroupVersion + scheme.AddKnownTypes(SchemeGroupVersion, + &PackageManifest{}, + &PackageManifestList{}, + ) + + return nil +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1/doc.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1/doc.go new file mode 100644 index 0000000000..69520a6408 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1/doc.go @@ -0,0 +1,7 @@ +// +k8s:deepcopy-gen=package +// +k8s:conversion-gen=github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators +// +k8s:defaulter-gen=TypeMeta +// +k8s:openapi-gen=true + +// +groupName=operators.coreos.com +package v1 diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1/packagemanifest.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1/packagemanifest.go similarity index 76% rename from vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1/packagemanifest.go rename to vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1/packagemanifest.go index d9278b5ddd..6bee85af51 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1/packagemanifest.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1/packagemanifest.go @@ -1,4 +1,4 @@ -package v1alpha1 +package v1 import operatorsv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" @@ -11,13 +11,16 @@ func CreateCSVDescription(csv *operatorsv1alpha1.ClusterServiceVersion) CSVDescr Name: csv.Spec.Provider.Name, URL: csv.Spec.Provider.URL, }, + Annotations: csv.GetAnnotations(), + LongDescription: csv.Spec.Description, + InstallModes: csv.Spec.InstallModes, } icons := make([]Icon, len(csv.Spec.Icon)) for i, icon := range csv.Spec.Icon { icons[i] = Icon{ - Data: icon.Data, - MediaType: icon.MediaType, + Base64Data: icon.Data, + Mediatype: icon.MediaType, } } diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1/packagemanifest_types.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1/packagemanifest_types.go new file mode 100644 index 0000000000..03ce64d486 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1/packagemanifest_types.go @@ -0,0 +1,123 @@ +package v1 + +import ( + "github.com/coreos/go-semver/semver" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + operatorv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" +) + +// PackageManifestList is a list of PackageManifest objects. +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type PackageManifestList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + + Items []PackageManifest `json:"items"` +} + +// PackageManifest holds information about a package, which is a reference to one (or more) +// channels under a single package. +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type PackageManifest struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec PackageManifestSpec `json:"spec,omitempty"` + Status PackageManifestStatus `json:"status,omitempty"` +} + +// PackageManifestSpec defines the desired state of PackageManifest +type PackageManifestSpec struct{} + +// PackageManifestStatus represents the current status of the PackageManifest +type PackageManifestStatus struct { + // CatalogSource is the name of the CatalogSource this package belongs to + CatalogSource string `json:"catalogSource"` + CatalogSourceDisplayName string `json:"catalogSourceDisplayName"` + CatalogSourcePublisher string `json:"catalogSourcePublisher"` + + // CatalogSourceNamespace is the namespace of the owning CatalogSource + CatalogSourceNamespace string `json:"catalogSourceNamespace"` + + // Provider is the provider of the PackageManifest's default CSV + Provider AppLink `json:"provider,omitempty"` + + // PackageName is the name of the overall package, ala `etcd`. + PackageName string `json:"packageName"` + + // Channels are the declared channels for the package, ala `stable` or `alpha`. + Channels []PackageChannel `json:"channels"` + + // DefaultChannel is, if specified, the name of the default channel for the package. The + // default channel will be installed if no other channel is explicitly given. If the package + // has a single channel, then that channel is implicitly the default. + DefaultChannel string `json:"defaultChannel"` +} + +// GetDefaultChannel gets the default channel or returns the only one if there's only one. returns empty string if it +// can't determine the default +func (m PackageManifest) GetDefaultChannel() string { + if m.Status.DefaultChannel != "" { + return m.Status.DefaultChannel + } + if len(m.Status.Channels) == 1 { + return m.Status.Channels[0].Name + } + return "" +} + +// PackageChannel defines a single channel under a package, pointing to a version of that +// package. +type PackageChannel struct { + // Name is the name of the channel, e.g. `alpha` or `stable` + Name string `json:"name"` + + // CurrentCSV defines a reference to the CSV holding the version of this package currently + // for the channel. + CurrentCSV string `json:"currentCSV"` + + // CurrentCSVSpec holds the spec of the current CSV + CurrentCSVDesc CSVDescription `json:"currentCSVDesc,omitempty"` +} + +// CSVDescription defines a description of a CSV +type CSVDescription struct { + // DisplayName is the CSV's display name + DisplayName string `json:"displayName,omitempty"` + + // Icon is the CSV's base64 encoded icon + Icon []Icon `json:"icon,omitempty"` + + // Version is the CSV's semantic version + // +k8s:openapi-gen=false + Version semver.Version `json:"version,omitempty"` + + // Provider is the CSV's provider + Provider AppLink `json:"provider,omitempty"` + Annotations map[string]string `json:"annotations,omitempty"` + + // LongDescription is the CSV's description + LongDescription string `json:"description,omitempty"` + + // InstallModes specify supported installation types + InstallModes []operatorv1alpha1.InstallMode `json:"installModes,omitempty"` +} + +// AppLink defines a link to an application +type AppLink struct { + Name string `json:"name,omitempty"` + URL string `json:"url,omitempty"` +} + +// Icon defines a base64 encoded icon and media type +type Icon struct { + Base64Data string `json:"base64data,omitempty"` + Mediatype string `json:"mediatype,omitempty"` +} + +// IsDefaultChannel returns true if the PackageChannel is the default for the PackageManifest +func (pc PackageChannel) IsDefaultChannel(pm PackageManifest) bool { + return pc.Name == pm.Status.DefaultChannel || len(pm.Status.Channels) == 1 +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1/register.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1/register.go new file mode 100644 index 0000000000..2b6a8fc66f --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1/register.go @@ -0,0 +1,45 @@ +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + + "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators" +) + +const ( + Group = "packages." + operators.GroupName + Version = "v1" + PackageManifestKind = "PackageManifest" + PackageManifestListKind = "PackageManifestList" +) + +// SchemeGroupVersion is the group version used to register these objects. +var SchemeGroupVersion = schema.GroupVersion{Group: Group, Version: Version} + +var ( + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + localSchemeBuilder = &SchemeBuilder + AddToScheme = localSchemeBuilder.AddToScheme +) + +// Resource takes an unqualified resource and returns a Group-qualified GroupResource. +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +// addKnownTypes adds the set of types defined in this package to the supplied scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypeWithName( + SchemeGroupVersion.WithKind(PackageManifestKind), + &PackageManifest{}, + ) + scheme.AddKnownTypeWithName( + SchemeGroupVersion.WithKind(PackageManifestListKind), + &PackageManifestList{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + + return nil +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1/zz_generated.conversion.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1/zz_generated.conversion.go new file mode 100644 index 0000000000..f11fc5b2b9 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1/zz_generated.conversion.go @@ -0,0 +1,338 @@ +// +build !ignore_autogenerated + +/* +Copyright 2019 Red Hat, 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 conversion-gen. DO NOT EDIT. + +package v1 + +import ( + unsafe "unsafe" + + v1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + operators "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators" + conversion "k8s.io/apimachinery/pkg/conversion" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +func init() { + localSchemeBuilder.Register(RegisterConversions) +} + +// RegisterConversions adds conversion functions to the given scheme. +// Public to allow building arbitrary schemes. +func RegisterConversions(s *runtime.Scheme) error { + if err := s.AddGeneratedConversionFunc((*AppLink)(nil), (*operators.AppLink)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_AppLink_To_operators_AppLink(a.(*AppLink), b.(*operators.AppLink), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*operators.AppLink)(nil), (*AppLink)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_operators_AppLink_To_v1_AppLink(a.(*operators.AppLink), b.(*AppLink), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*CSVDescription)(nil), (*operators.CSVDescription)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_CSVDescription_To_operators_CSVDescription(a.(*CSVDescription), b.(*operators.CSVDescription), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*operators.CSVDescription)(nil), (*CSVDescription)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_operators_CSVDescription_To_v1_CSVDescription(a.(*operators.CSVDescription), b.(*CSVDescription), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*Icon)(nil), (*operators.Icon)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_Icon_To_operators_Icon(a.(*Icon), b.(*operators.Icon), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*operators.Icon)(nil), (*Icon)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_operators_Icon_To_v1_Icon(a.(*operators.Icon), b.(*Icon), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*PackageChannel)(nil), (*operators.PackageChannel)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_PackageChannel_To_operators_PackageChannel(a.(*PackageChannel), b.(*operators.PackageChannel), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*operators.PackageChannel)(nil), (*PackageChannel)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_operators_PackageChannel_To_v1_PackageChannel(a.(*operators.PackageChannel), b.(*PackageChannel), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*PackageManifest)(nil), (*operators.PackageManifest)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_PackageManifest_To_operators_PackageManifest(a.(*PackageManifest), b.(*operators.PackageManifest), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*operators.PackageManifest)(nil), (*PackageManifest)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_operators_PackageManifest_To_v1_PackageManifest(a.(*operators.PackageManifest), b.(*PackageManifest), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*PackageManifestList)(nil), (*operators.PackageManifestList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_PackageManifestList_To_operators_PackageManifestList(a.(*PackageManifestList), b.(*operators.PackageManifestList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*operators.PackageManifestList)(nil), (*PackageManifestList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_operators_PackageManifestList_To_v1_PackageManifestList(a.(*operators.PackageManifestList), b.(*PackageManifestList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*PackageManifestSpec)(nil), (*operators.PackageManifestSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_PackageManifestSpec_To_operators_PackageManifestSpec(a.(*PackageManifestSpec), b.(*operators.PackageManifestSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*operators.PackageManifestSpec)(nil), (*PackageManifestSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_operators_PackageManifestSpec_To_v1_PackageManifestSpec(a.(*operators.PackageManifestSpec), b.(*PackageManifestSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*PackageManifestStatus)(nil), (*operators.PackageManifestStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_PackageManifestStatus_To_operators_PackageManifestStatus(a.(*PackageManifestStatus), b.(*operators.PackageManifestStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*operators.PackageManifestStatus)(nil), (*PackageManifestStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_operators_PackageManifestStatus_To_v1_PackageManifestStatus(a.(*operators.PackageManifestStatus), b.(*PackageManifestStatus), scope) + }); err != nil { + return err + } + return nil +} + +func autoConvert_v1_AppLink_To_operators_AppLink(in *AppLink, out *operators.AppLink, s conversion.Scope) error { + out.Name = in.Name + out.URL = in.URL + return nil +} + +// Convert_v1_AppLink_To_operators_AppLink is an autogenerated conversion function. +func Convert_v1_AppLink_To_operators_AppLink(in *AppLink, out *operators.AppLink, s conversion.Scope) error { + return autoConvert_v1_AppLink_To_operators_AppLink(in, out, s) +} + +func autoConvert_operators_AppLink_To_v1_AppLink(in *operators.AppLink, out *AppLink, s conversion.Scope) error { + out.Name = in.Name + out.URL = in.URL + return nil +} + +// Convert_operators_AppLink_To_v1_AppLink is an autogenerated conversion function. +func Convert_operators_AppLink_To_v1_AppLink(in *operators.AppLink, out *AppLink, s conversion.Scope) error { + return autoConvert_operators_AppLink_To_v1_AppLink(in, out, s) +} + +func autoConvert_v1_CSVDescription_To_operators_CSVDescription(in *CSVDescription, out *operators.CSVDescription, s conversion.Scope) error { + out.DisplayName = in.DisplayName + out.Icon = *(*[]operators.Icon)(unsafe.Pointer(&in.Icon)) + out.Version = in.Version + if err := Convert_v1_AppLink_To_operators_AppLink(&in.Provider, &out.Provider, s); err != nil { + return err + } + out.Annotations = *(*map[string]string)(unsafe.Pointer(&in.Annotations)) + out.LongDescription = in.LongDescription + out.InstallModes = *(*[]v1alpha1.InstallMode)(unsafe.Pointer(&in.InstallModes)) + return nil +} + +// Convert_v1_CSVDescription_To_operators_CSVDescription is an autogenerated conversion function. +func Convert_v1_CSVDescription_To_operators_CSVDescription(in *CSVDescription, out *operators.CSVDescription, s conversion.Scope) error { + return autoConvert_v1_CSVDescription_To_operators_CSVDescription(in, out, s) +} + +func autoConvert_operators_CSVDescription_To_v1_CSVDescription(in *operators.CSVDescription, out *CSVDescription, s conversion.Scope) error { + out.DisplayName = in.DisplayName + out.Icon = *(*[]Icon)(unsafe.Pointer(&in.Icon)) + out.Version = in.Version + if err := Convert_operators_AppLink_To_v1_AppLink(&in.Provider, &out.Provider, s); err != nil { + return err + } + out.Annotations = *(*map[string]string)(unsafe.Pointer(&in.Annotations)) + out.LongDescription = in.LongDescription + out.InstallModes = *(*[]v1alpha1.InstallMode)(unsafe.Pointer(&in.InstallModes)) + return nil +} + +// Convert_operators_CSVDescription_To_v1_CSVDescription is an autogenerated conversion function. +func Convert_operators_CSVDescription_To_v1_CSVDescription(in *operators.CSVDescription, out *CSVDescription, s conversion.Scope) error { + return autoConvert_operators_CSVDescription_To_v1_CSVDescription(in, out, s) +} + +func autoConvert_v1_Icon_To_operators_Icon(in *Icon, out *operators.Icon, s conversion.Scope) error { + out.Base64Data = in.Base64Data + out.Mediatype = in.Mediatype + return nil +} + +// Convert_v1_Icon_To_operators_Icon is an autogenerated conversion function. +func Convert_v1_Icon_To_operators_Icon(in *Icon, out *operators.Icon, s conversion.Scope) error { + return autoConvert_v1_Icon_To_operators_Icon(in, out, s) +} + +func autoConvert_operators_Icon_To_v1_Icon(in *operators.Icon, out *Icon, s conversion.Scope) error { + out.Base64Data = in.Base64Data + out.Mediatype = in.Mediatype + return nil +} + +// Convert_operators_Icon_To_v1_Icon is an autogenerated conversion function. +func Convert_operators_Icon_To_v1_Icon(in *operators.Icon, out *Icon, s conversion.Scope) error { + return autoConvert_operators_Icon_To_v1_Icon(in, out, s) +} + +func autoConvert_v1_PackageChannel_To_operators_PackageChannel(in *PackageChannel, out *operators.PackageChannel, s conversion.Scope) error { + out.Name = in.Name + out.CurrentCSV = in.CurrentCSV + if err := Convert_v1_CSVDescription_To_operators_CSVDescription(&in.CurrentCSVDesc, &out.CurrentCSVDesc, s); err != nil { + return err + } + return nil +} + +// Convert_v1_PackageChannel_To_operators_PackageChannel is an autogenerated conversion function. +func Convert_v1_PackageChannel_To_operators_PackageChannel(in *PackageChannel, out *operators.PackageChannel, s conversion.Scope) error { + return autoConvert_v1_PackageChannel_To_operators_PackageChannel(in, out, s) +} + +func autoConvert_operators_PackageChannel_To_v1_PackageChannel(in *operators.PackageChannel, out *PackageChannel, s conversion.Scope) error { + out.Name = in.Name + out.CurrentCSV = in.CurrentCSV + if err := Convert_operators_CSVDescription_To_v1_CSVDescription(&in.CurrentCSVDesc, &out.CurrentCSVDesc, s); err != nil { + return err + } + return nil +} + +// Convert_operators_PackageChannel_To_v1_PackageChannel is an autogenerated conversion function. +func Convert_operators_PackageChannel_To_v1_PackageChannel(in *operators.PackageChannel, out *PackageChannel, s conversion.Scope) error { + return autoConvert_operators_PackageChannel_To_v1_PackageChannel(in, out, s) +} + +func autoConvert_v1_PackageManifest_To_operators_PackageManifest(in *PackageManifest, out *operators.PackageManifest, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1_PackageManifestSpec_To_operators_PackageManifestSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v1_PackageManifestStatus_To_operators_PackageManifestStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +// Convert_v1_PackageManifest_To_operators_PackageManifest is an autogenerated conversion function. +func Convert_v1_PackageManifest_To_operators_PackageManifest(in *PackageManifest, out *operators.PackageManifest, s conversion.Scope) error { + return autoConvert_v1_PackageManifest_To_operators_PackageManifest(in, out, s) +} + +func autoConvert_operators_PackageManifest_To_v1_PackageManifest(in *operators.PackageManifest, out *PackageManifest, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_operators_PackageManifestSpec_To_v1_PackageManifestSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_operators_PackageManifestStatus_To_v1_PackageManifestStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +// Convert_operators_PackageManifest_To_v1_PackageManifest is an autogenerated conversion function. +func Convert_operators_PackageManifest_To_v1_PackageManifest(in *operators.PackageManifest, out *PackageManifest, s conversion.Scope) error { + return autoConvert_operators_PackageManifest_To_v1_PackageManifest(in, out, s) +} + +func autoConvert_v1_PackageManifestList_To_operators_PackageManifestList(in *PackageManifestList, out *operators.PackageManifestList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + out.Items = *(*[]operators.PackageManifest)(unsafe.Pointer(&in.Items)) + return nil +} + +// Convert_v1_PackageManifestList_To_operators_PackageManifestList is an autogenerated conversion function. +func Convert_v1_PackageManifestList_To_operators_PackageManifestList(in *PackageManifestList, out *operators.PackageManifestList, s conversion.Scope) error { + return autoConvert_v1_PackageManifestList_To_operators_PackageManifestList(in, out, s) +} + +func autoConvert_operators_PackageManifestList_To_v1_PackageManifestList(in *operators.PackageManifestList, out *PackageManifestList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + out.Items = *(*[]PackageManifest)(unsafe.Pointer(&in.Items)) + return nil +} + +// Convert_operators_PackageManifestList_To_v1_PackageManifestList is an autogenerated conversion function. +func Convert_operators_PackageManifestList_To_v1_PackageManifestList(in *operators.PackageManifestList, out *PackageManifestList, s conversion.Scope) error { + return autoConvert_operators_PackageManifestList_To_v1_PackageManifestList(in, out, s) +} + +func autoConvert_v1_PackageManifestSpec_To_operators_PackageManifestSpec(in *PackageManifestSpec, out *operators.PackageManifestSpec, s conversion.Scope) error { + return nil +} + +// Convert_v1_PackageManifestSpec_To_operators_PackageManifestSpec is an autogenerated conversion function. +func Convert_v1_PackageManifestSpec_To_operators_PackageManifestSpec(in *PackageManifestSpec, out *operators.PackageManifestSpec, s conversion.Scope) error { + return autoConvert_v1_PackageManifestSpec_To_operators_PackageManifestSpec(in, out, s) +} + +func autoConvert_operators_PackageManifestSpec_To_v1_PackageManifestSpec(in *operators.PackageManifestSpec, out *PackageManifestSpec, s conversion.Scope) error { + return nil +} + +// Convert_operators_PackageManifestSpec_To_v1_PackageManifestSpec is an autogenerated conversion function. +func Convert_operators_PackageManifestSpec_To_v1_PackageManifestSpec(in *operators.PackageManifestSpec, out *PackageManifestSpec, s conversion.Scope) error { + return autoConvert_operators_PackageManifestSpec_To_v1_PackageManifestSpec(in, out, s) +} + +func autoConvert_v1_PackageManifestStatus_To_operators_PackageManifestStatus(in *PackageManifestStatus, out *operators.PackageManifestStatus, s conversion.Scope) error { + out.CatalogSource = in.CatalogSource + out.CatalogSourceDisplayName = in.CatalogSourceDisplayName + out.CatalogSourcePublisher = in.CatalogSourcePublisher + out.CatalogSourceNamespace = in.CatalogSourceNamespace + if err := Convert_v1_AppLink_To_operators_AppLink(&in.Provider, &out.Provider, s); err != nil { + return err + } + out.PackageName = in.PackageName + out.Channels = *(*[]operators.PackageChannel)(unsafe.Pointer(&in.Channels)) + out.DefaultChannel = in.DefaultChannel + return nil +} + +// Convert_v1_PackageManifestStatus_To_operators_PackageManifestStatus is an autogenerated conversion function. +func Convert_v1_PackageManifestStatus_To_operators_PackageManifestStatus(in *PackageManifestStatus, out *operators.PackageManifestStatus, s conversion.Scope) error { + return autoConvert_v1_PackageManifestStatus_To_operators_PackageManifestStatus(in, out, s) +} + +func autoConvert_operators_PackageManifestStatus_To_v1_PackageManifestStatus(in *operators.PackageManifestStatus, out *PackageManifestStatus, s conversion.Scope) error { + out.CatalogSource = in.CatalogSource + out.CatalogSourceDisplayName = in.CatalogSourceDisplayName + out.CatalogSourcePublisher = in.CatalogSourcePublisher + out.CatalogSourceNamespace = in.CatalogSourceNamespace + if err := Convert_operators_AppLink_To_v1_AppLink(&in.Provider, &out.Provider, s); err != nil { + return err + } + out.PackageName = in.PackageName + out.Channels = *(*[]PackageChannel)(unsafe.Pointer(&in.Channels)) + out.DefaultChannel = in.DefaultChannel + return nil +} + +// Convert_operators_PackageManifestStatus_To_v1_PackageManifestStatus is an autogenerated conversion function. +func Convert_operators_PackageManifestStatus_To_v1_PackageManifestStatus(in *operators.PackageManifestStatus, out *PackageManifestStatus, s conversion.Scope) error { + return autoConvert_operators_PackageManifestStatus_To_v1_PackageManifestStatus(in, out, s) +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1/zz_generated.deepcopy.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1/zz_generated.deepcopy.go similarity index 92% rename from vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1/zz_generated.deepcopy.go rename to vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1/zz_generated.deepcopy.go index aba59fdaad..0c4534473b 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1/zz_generated.deepcopy.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1/zz_generated.deepcopy.go @@ -1,7 +1,7 @@ // +build !ignore_autogenerated /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -18,9 +18,10 @@ limitations under the License. // Code generated by deepcopy-gen. DO NOT EDIT. -package v1alpha1 +package v1 import ( + v1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -50,6 +51,18 @@ func (in *CSVDescription) DeepCopyInto(out *CSVDescription) { } out.Version = in.Version out.Provider = in.Provider + 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 + } + } + if in.InstallModes != nil { + in, out := &in.InstallModes, &out.InstallModes + *out = make([]v1alpha1.InstallMode, len(*in)) + copy(*out, *in) + } return } diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1/zz_generated.defaults.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1/zz_generated.defaults.go new file mode 100644 index 0000000000..41c150b3bf --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1/zz_generated.defaults.go @@ -0,0 +1,32 @@ +// +build !ignore_autogenerated + +/* +Copyright 2019 Red Hat, 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 defaulter-gen. DO NOT EDIT. + +package v1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// RegisterDefaults adds defaulters functions to the given scheme. +// Public to allow building arbitrary schemes. +// All generated defaulters are covering - they call all nested defaulters. +func RegisterDefaults(scheme *runtime.Scheme) error { + return nil +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/zz_generated.deepcopy.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/zz_generated.deepcopy.go new file mode 100644 index 0000000000..719847ddeb --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/zz_generated.deepcopy.go @@ -0,0 +1,211 @@ +// +build !ignore_autogenerated + +/* +Copyright 2019 Red Hat, 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 deepcopy-gen. DO NOT EDIT. + +package operators + +import ( + v1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + 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 *AppLink) DeepCopyInto(out *AppLink) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppLink. +func (in *AppLink) DeepCopy() *AppLink { + if in == nil { + return nil + } + out := new(AppLink) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CSVDescription) DeepCopyInto(out *CSVDescription) { + *out = *in + if in.Icon != nil { + in, out := &in.Icon, &out.Icon + *out = make([]Icon, len(*in)) + copy(*out, *in) + } + out.Version = in.Version + out.Provider = in.Provider + 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 + } + } + if in.InstallModes != nil { + in, out := &in.InstallModes, &out.InstallModes + *out = make([]v1alpha1.InstallMode, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CSVDescription. +func (in *CSVDescription) DeepCopy() *CSVDescription { + if in == nil { + return nil + } + out := new(CSVDescription) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Icon) DeepCopyInto(out *Icon) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Icon. +func (in *Icon) DeepCopy() *Icon { + if in == nil { + return nil + } + out := new(Icon) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PackageChannel) DeepCopyInto(out *PackageChannel) { + *out = *in + in.CurrentCSVDesc.DeepCopyInto(&out.CurrentCSVDesc) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageChannel. +func (in *PackageChannel) DeepCopy() *PackageChannel { + if in == nil { + return nil + } + out := new(PackageChannel) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PackageManifest) DeepCopyInto(out *PackageManifest) { + *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 PackageManifest. +func (in *PackageManifest) DeepCopy() *PackageManifest { + if in == nil { + return nil + } + out := new(PackageManifest) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PackageManifest) 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 *PackageManifestList) DeepCopyInto(out *PackageManifestList) { + *out = *in + out.TypeMeta = in.TypeMeta + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]PackageManifest, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageManifestList. +func (in *PackageManifestList) DeepCopy() *PackageManifestList { + if in == nil { + return nil + } + out := new(PackageManifestList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PackageManifestList) 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 *PackageManifestSpec) DeepCopyInto(out *PackageManifestSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageManifestSpec. +func (in *PackageManifestSpec) DeepCopy() *PackageManifestSpec { + if in == nil { + return nil + } + out := new(PackageManifestSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PackageManifestStatus) DeepCopyInto(out *PackageManifestStatus) { + *out = *in + out.Provider = in.Provider + if in.Channels != nil { + in, out := &in.Channels, &out.Channels + *out = make([]PackageChannel, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageManifestStatus. +func (in *PackageManifestStatus) DeepCopy() *PackageManifestStatus { + if in == nil { + return nil + } + out := new(PackageManifestStatus) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/install/install.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/install/install.go deleted file mode 100644 index 839181f144..0000000000 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/install/install.go +++ /dev/null @@ -1,11 +0,0 @@ -package install - -import ( - "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1" - "k8s.io/apimachinery/pkg/runtime" -) - -// Install registers the API group and adds types to a scheme -func Install(scheme *runtime.Scheme) { - v1alpha1.AddToScheme(scheme) -} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1/doc.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1/doc.go deleted file mode 100644 index c247979145..0000000000 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// +k8s:deepcopy-gen=package -// +k8s:openapi-gen=true -package v1alpha1 diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apiserver/config.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apiserver/config.go index 17dc4fd9fb..0e497c29b9 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apiserver/config.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apiserver/config.go @@ -17,43 +17,15 @@ package apiserver import ( "strings" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/runtime/serializer" openapinamer "k8s.io/apiserver/pkg/endpoints/openapi" genericapiserver "k8s.io/apiserver/pkg/server" "k8s.io/client-go/informers" - "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/install" + generatedopenapi "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/openapi" "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apiserver/generic" - generatedopenapi "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/generated/openapi" "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/version" ) -var ( - Scheme = runtime.NewScheme() - Codecs = serializer.NewCodecFactory(Scheme) -) - -func init() { - install.Install(Scheme) - - // we need to add the options to empty v1 - // TODO fix the server code to avoid this - metav1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"}) - - // TODO: keep the generic API server from wanting this - unversioned := schema.GroupVersion{Group: "", Version: "v1"} - Scheme.AddUnversionedTypes(unversioned, - &metav1.Status{}, - &metav1.APIVersions{}, - &metav1.APIGroupList{}, - &metav1.APIGroup{}, - &metav1.APIResourceList{}, - ) -} - // Config contains configuration for launching an instance of metrics-server. type Config struct { GenericConfig *genericapiserver.Config diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apiserver/generic/storage.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apiserver/generic/storage.go index 0a9fa8e60d..daf1298394 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apiserver/generic/storage.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apiserver/generic/storage.go @@ -19,13 +19,16 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/serializer" + utilerrors "k8s.io/apimachinery/pkg/util/errors" "k8s.io/apiserver/pkg/registry/rest" - genericapiserver "k8s.io/apiserver/pkg/server" + generic "k8s.io/apiserver/pkg/server" - "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/install" - packagemanifest "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1" + apps "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/install" + "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1" + operators "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/install" + v1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1" "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/provider" - packagemanifeststorage "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/storage/packagemanifest" + "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/storage" ) var ( @@ -36,31 +39,63 @@ var ( ) func init() { - install.Install(Scheme) + operators.Install(Scheme) + apps.Install(Scheme) + + // we need to add the options to empty v1 + // TODO fix the server code to avoid this metav1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"}) + + // TODO: keep the generic API server from wanting this + unversioned := schema.GroupVersion{Group: "", Version: "v1"} + Scheme.AddUnversionedTypes(unversioned, + &metav1.Status{}, + &metav1.APIVersions{}, + &metav1.APIGroupList{}, + &metav1.APIGroup{}, + &metav1.APIResourceList{}, + ) } -// ProviderConfig holds the providers for node and pod metrics -// for serving the resource metrics API. +// ProviderConfig holds the providers for packagemanifests. type ProviderConfig struct { Provider provider.PackageManifestProvider } -// BuildStorage constructs APIGroupInfo the metrics.k8s.io API group using the given providers. -func BuildStorage(providers *ProviderConfig) genericapiserver.APIGroupInfo { - apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(packagemanifest.Group, Scheme, metav1.ParameterCodec, Codecs) +// BuildStorage constructs APIGroupInfo for the packages.apps.redhat.com and packages.operators.coreos.com API groups. +func BuildStorage(providers *ProviderConfig) []generic.APIGroupInfo { + + // Build storage for packages.operators.coreos.com + operatorInfo := generic.NewDefaultAPIGroupInfo(v1.Group, Scheme, metav1.ParameterCodec, Codecs) + operatorStorage := storage.NewStorage(v1.Resource("packagemanifests"), providers.Provider, Scheme) + operatorResources := map[string]rest.Storage{ + "packagemanifests": operatorStorage, + } + operatorInfo.VersionedResourcesStorageMap[v1.Version] = operatorResources + + // Build storage for packages.apps.redhat.com + appInfo := generic.NewDefaultAPIGroupInfo(v1alpha1.Group, Scheme, metav1.ParameterCodec, Codecs) - packageManifestStorage := packagemanifeststorage.NewStorage(packagemanifest.Resource("packagemanifests"), providers.Provider) - packageManifestResources := map[string]rest.Storage{ - "packagemanifests": packageManifestStorage, + // Use storage for package.operators.coreos.com since types are identical + appResources := map[string]rest.Storage{ + "packagemanifests": operatorStorage, } - apiGroupInfo.VersionedResourcesStorageMap[packagemanifest.Version] = packageManifestResources + appInfo.VersionedResourcesStorageMap[v1alpha1.Version] = appResources - return apiGroupInfo + return []generic.APIGroupInfo{ + operatorInfo, + appInfo, + } } -// InstallStorage builds the storage for the metrics.k8s.io API, and then installs it into the given API server. -func InstallStorage(providers *ProviderConfig, server *genericapiserver.GenericAPIServer) error { - info := BuildStorage(providers) - return server.InstallAPIGroup(&info) +// InstallStorage builds the storage for the packages.apps.redhat.com and packages.operators.coreos.com API groups and then installs them into the given API server. +func InstallStorage(providers *ProviderConfig, server *generic.GenericAPIServer) error { + errs := []error{} + groups := BuildStorage(providers) + for i := 0; i < len(groups); i++ { + info := groups[i] + errs = append(errs, server.InstallAPIGroup(&info)) + } + + return utilerrors.NewAggregate(errs) } diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/clientset.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/clientset.go new file mode 100644 index 0000000000..d5665e4857 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/clientset.go @@ -0,0 +1,104 @@ +/* +Copyright 2019 Red Hat, 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 client-gen. DO NOT EDIT. + +package internalversion + +import ( + appsinternalversion "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/apps/internalversion" + operatorsinternalversion "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/operators/internalversion" + 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 + Apps() appsinternalversion.AppsInterface + Operators() operatorsinternalversion.OperatorsInterface +} + +// Clientset contains the clients for groups. Each group has exactly one +// version included in a Clientset. +type Clientset struct { + *discovery.DiscoveryClient + apps *appsinternalversion.AppsClient + operators *operatorsinternalversion.OperatorsClient +} + +// Apps retrieves the AppsClient +func (c *Clientset) Apps() appsinternalversion.AppsInterface { + return c.apps +} + +// Operators retrieves the OperatorsClient +func (c *Clientset) Operators() operatorsinternalversion.OperatorsInterface { + return c.operators +} + +// 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. +func NewForConfig(c *rest.Config) (*Clientset, error) { + configShallowCopy := *c + if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 { + configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst) + } + var cs Clientset + var err error + cs.apps, err = appsinternalversion.NewForConfig(&configShallowCopy) + if err != nil { + return nil, err + } + cs.operators, err = operatorsinternalversion.NewForConfig(&configShallowCopy) + if err != nil { + return nil, err + } + + cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy) + 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 { + var cs Clientset + cs.apps = appsinternalversion.NewForConfigOrDie(c) + cs.operators = operatorsinternalversion.NewForConfigOrDie(c) + + cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c) + return &cs +} + +// New creates a new Clientset for the given RESTClient. +func New(c rest.Interface) *Clientset { + var cs Clientset + cs.apps = appsinternalversion.New(c) + cs.operators = operatorsinternalversion.New(c) + + cs.DiscoveryClient = discovery.NewDiscoveryClient(c) + return &cs +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/doc.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/doc.go new file mode 100644 index 0000000000..676a0fe259 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2019 Red Hat, 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 client-gen. DO NOT EDIT. + +// This package has the automatically generated clientset. +package internalversion diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/fake/clientset_generated.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/fake/clientset_generated.go new file mode 100644 index 0000000000..16163f86b2 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/fake/clientset_generated.go @@ -0,0 +1,84 @@ +/* +Copyright 2019 Red Hat, 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 client-gen. DO NOT EDIT. + +package fake + +import ( + clientset "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion" + appsinternalversion "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/apps/internalversion" + fakeappsinternalversion "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/apps/internalversion/fake" + operatorsinternalversion "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/operators/internalversion" + fakeoperatorsinternalversion "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/operators/internalversion/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{} + 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 +} + +func (c *Clientset) Discovery() discovery.DiscoveryInterface { + return c.discovery +} + +var _ clientset.Interface = &Clientset{} + +// Apps retrieves the AppsClient +func (c *Clientset) Apps() appsinternalversion.AppsInterface { + return &fakeappsinternalversion.FakeApps{Fake: &c.Fake} +} + +// Operators retrieves the OperatorsClient +func (c *Clientset) Operators() operatorsinternalversion.OperatorsInterface { + return &fakeoperatorsinternalversion.FakeOperators{Fake: &c.Fake} +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/fake/doc.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/fake/doc.go new file mode 100644 index 0000000000..ee22a9450f --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/fake/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2019 Red Hat, 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 client-gen. DO NOT EDIT. + +// This package has the automatically generated fake clientset. +package fake diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/fake/register.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/fake/register.go new file mode 100644 index 0000000000..f687c9b2a8 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/fake/register.go @@ -0,0 +1,58 @@ +/* +Copyright 2019 Red Hat, 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 client-gen. DO NOT EDIT. + +package fake + +import ( + appsinternalversion "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps" + operatorsinternalversion "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators" + 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{ + appsinternalversion.AddToScheme, + operatorsinternalversion.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/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/scheme/doc.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/scheme/doc.go new file mode 100644 index 0000000000..25323d1083 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/scheme/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2019 Red Hat, 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 client-gen. DO NOT EDIT. + +// This package contains the scheme of the automatically generated clientset. +package scheme diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/scheme/register.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/scheme/register.go new file mode 100644 index 0000000000..461b923827 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/scheme/register.go @@ -0,0 +1,43 @@ +/* +Copyright 2019 Red Hat, 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 client-gen. DO NOT EDIT. + +package scheme + +import ( + apps "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/install" + operators "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/install" + 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" +) + +var Scheme = runtime.NewScheme() +var Codecs = serializer.NewCodecFactory(Scheme) +var ParameterCodec = runtime.NewParameterCodec(Scheme) + +func init() { + v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"}) + Install(Scheme) +} + +// Install registers the API group and adds types to a scheme +func Install(scheme *runtime.Scheme) { + apps.Install(scheme) + operators.Install(scheme) +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/apps/internalversion/apps_client.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/apps/internalversion/apps_client.go new file mode 100644 index 0000000000..30a4702d71 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/apps/internalversion/apps_client.go @@ -0,0 +1,91 @@ +/* +Copyright 2019 Red Hat, 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 client-gen. DO NOT EDIT. + +package internalversion + +import ( + "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/scheme" + rest "k8s.io/client-go/rest" +) + +type AppsInterface interface { + RESTClient() rest.Interface +} + +// AppsClient is used to interact with features provided by the apps group. +type AppsClient struct { + restClient rest.Interface +} + +// NewForConfig creates a new AppsClient for the given config. +func NewForConfig(c *rest.Config) (*AppsClient, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientFor(&config) + if err != nil { + return nil, err + } + return &AppsClient{client}, nil +} + +// NewForConfigOrDie creates a new AppsClient for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *AppsClient { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new AppsClient for the given RESTClient. +func New(c rest.Interface) *AppsClient { + return &AppsClient{c} +} + +func setConfigDefaults(config *rest.Config) error { + config.APIPath = "/apis" + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } + if config.GroupVersion == nil || config.GroupVersion.Group != scheme.Scheme.PrioritizedVersionsForGroup("apps")[0].Group { + gv := scheme.Scheme.PrioritizedVersionsForGroup("apps")[0] + config.GroupVersion = &gv + } + config.NegotiatedSerializer = scheme.Codecs + + if config.QPS == 0 { + config.QPS = 5 + } + if config.Burst == 0 { + config.Burst = 10 + } + + return nil +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *AppsClient) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/apps/internalversion/doc.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/apps/internalversion/doc.go new file mode 100644 index 0000000000..8be96d7328 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/apps/internalversion/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2019 Red Hat, 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 client-gen. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package internalversion diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/apps/internalversion/fake/doc.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/apps/internalversion/fake/doc.go new file mode 100644 index 0000000000..da6f0eb8e5 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/apps/internalversion/fake/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2019 Red Hat, 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 client-gen. DO NOT EDIT. + +// Package fake has the automatically generated clients. +package fake diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/apps/internalversion/fake/fake_apps_client.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/apps/internalversion/fake/fake_apps_client.go new file mode 100644 index 0000000000..b9de320cc5 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/apps/internalversion/fake/fake_apps_client.go @@ -0,0 +1,35 @@ +/* +Copyright 2019 Red Hat, 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 client-gen. DO NOT EDIT. + +package fake + +import ( + rest "k8s.io/client-go/rest" + testing "k8s.io/client-go/testing" +) + +type FakeApps struct { + *testing.Fake +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *FakeApps) RESTClient() rest.Interface { + var ret *rest.RESTClient + return ret +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/apps/internalversion/generated_expansion.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/apps/internalversion/generated_expansion.go new file mode 100644 index 0000000000..1ffc8deb0d --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/apps/internalversion/generated_expansion.go @@ -0,0 +1,19 @@ +/* +Copyright 2019 Red Hat, 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 client-gen. DO NOT EDIT. + +package internalversion diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/operators/internalversion/doc.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/operators/internalversion/doc.go new file mode 100644 index 0000000000..8be96d7328 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/operators/internalversion/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2019 Red Hat, 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 client-gen. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package internalversion diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/operators/internalversion/fake/doc.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/operators/internalversion/fake/doc.go new file mode 100644 index 0000000000..da6f0eb8e5 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/operators/internalversion/fake/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2019 Red Hat, 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 client-gen. DO NOT EDIT. + +// Package fake has the automatically generated clients. +package fake diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/operators/internalversion/fake/fake_operators_client.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/operators/internalversion/fake/fake_operators_client.go new file mode 100644 index 0000000000..cebcdcda88 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/operators/internalversion/fake/fake_operators_client.go @@ -0,0 +1,40 @@ +/* +Copyright 2019 Red Hat, 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 client-gen. DO NOT EDIT. + +package fake + +import ( + internalversion "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/operators/internalversion" + rest "k8s.io/client-go/rest" + testing "k8s.io/client-go/testing" +) + +type FakeOperators struct { + *testing.Fake +} + +func (c *FakeOperators) PackageManifests(namespace string) internalversion.PackageManifestInterface { + return &FakePackageManifests{c, namespace} +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *FakeOperators) RESTClient() rest.Interface { + var ret *rest.RESTClient + return ret +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/operators/internalversion/fake/fake_packagemanifest.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/operators/internalversion/fake/fake_packagemanifest.go new file mode 100644 index 0000000000..d57470addb --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/operators/internalversion/fake/fake_packagemanifest.go @@ -0,0 +1,140 @@ +/* +Copyright 2019 Red Hat, 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 client-gen. DO NOT EDIT. + +package fake + +import ( + operators "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + schema "k8s.io/apimachinery/pkg/runtime/schema" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakePackageManifests implements PackageManifestInterface +type FakePackageManifests struct { + Fake *FakeOperators + ns string +} + +var packagemanifestsResource = schema.GroupVersionResource{Group: "operators.coreos.com", Version: "", Resource: "packagemanifests"} + +var packagemanifestsKind = schema.GroupVersionKind{Group: "operators.coreos.com", Version: "", Kind: "PackageManifest"} + +// Get takes name of the packageManifest, and returns the corresponding packageManifest object, and an error if there is any. +func (c *FakePackageManifests) Get(name string, options v1.GetOptions) (result *operators.PackageManifest, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(packagemanifestsResource, c.ns, name), &operators.PackageManifest{}) + + if obj == nil { + return nil, err + } + return obj.(*operators.PackageManifest), err +} + +// List takes label and field selectors, and returns the list of PackageManifests that match those selectors. +func (c *FakePackageManifests) List(opts v1.ListOptions) (result *operators.PackageManifestList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(packagemanifestsResource, packagemanifestsKind, c.ns, opts), &operators.PackageManifestList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &operators.PackageManifestList{ListMeta: obj.(*operators.PackageManifestList).ListMeta} + for _, item := range obj.(*operators.PackageManifestList).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 packageManifests. +func (c *FakePackageManifests) Watch(opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(packagemanifestsResource, c.ns, opts)) + +} + +// Create takes the representation of a packageManifest and creates it. Returns the server's representation of the packageManifest, and an error, if there is any. +func (c *FakePackageManifests) Create(packageManifest *operators.PackageManifest) (result *operators.PackageManifest, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(packagemanifestsResource, c.ns, packageManifest), &operators.PackageManifest{}) + + if obj == nil { + return nil, err + } + return obj.(*operators.PackageManifest), err +} + +// Update takes the representation of a packageManifest and updates it. Returns the server's representation of the packageManifest, and an error, if there is any. +func (c *FakePackageManifests) Update(packageManifest *operators.PackageManifest) (result *operators.PackageManifest, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(packagemanifestsResource, c.ns, packageManifest), &operators.PackageManifest{}) + + if obj == nil { + return nil, err + } + return obj.(*operators.PackageManifest), 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 *FakePackageManifests) UpdateStatus(packageManifest *operators.PackageManifest) (*operators.PackageManifest, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(packagemanifestsResource, "status", c.ns, packageManifest), &operators.PackageManifest{}) + + if obj == nil { + return nil, err + } + return obj.(*operators.PackageManifest), err +} + +// Delete takes name of the packageManifest and deletes it. Returns an error if one occurs. +func (c *FakePackageManifests) Delete(name string, options *v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteAction(packagemanifestsResource, c.ns, name), &operators.PackageManifest{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakePackageManifests) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(packagemanifestsResource, c.ns, listOptions) + + _, err := c.Fake.Invokes(action, &operators.PackageManifestList{}) + return err +} + +// Patch applies the patch and returns the patched packageManifest. +func (c *FakePackageManifests) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *operators.PackageManifest, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(packagemanifestsResource, c.ns, name, data, subresources...), &operators.PackageManifest{}) + + if obj == nil { + return nil, err + } + return obj.(*operators.PackageManifest), err +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/operators/internalversion/generated_expansion.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/operators/internalversion/generated_expansion.go new file mode 100644 index 0000000000..1b4155141a --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/operators/internalversion/generated_expansion.go @@ -0,0 +1,21 @@ +/* +Copyright 2019 Red Hat, 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 client-gen. DO NOT EDIT. + +package internalversion + +type PackageManifestExpansion interface{} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/operators/internalversion/operators_client.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/operators/internalversion/operators_client.go new file mode 100644 index 0000000000..6107bdb529 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/operators/internalversion/operators_client.go @@ -0,0 +1,96 @@ +/* +Copyright 2019 Red Hat, 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 client-gen. DO NOT EDIT. + +package internalversion + +import ( + "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/scheme" + rest "k8s.io/client-go/rest" +) + +type OperatorsInterface interface { + RESTClient() rest.Interface + PackageManifestsGetter +} + +// OperatorsClient is used to interact with features provided by the operators.coreos.com group. +type OperatorsClient struct { + restClient rest.Interface +} + +func (c *OperatorsClient) PackageManifests(namespace string) PackageManifestInterface { + return newPackageManifests(c, namespace) +} + +// NewForConfig creates a new OperatorsClient for the given config. +func NewForConfig(c *rest.Config) (*OperatorsClient, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientFor(&config) + if err != nil { + return nil, err + } + return &OperatorsClient{client}, nil +} + +// NewForConfigOrDie creates a new OperatorsClient for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *OperatorsClient { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new OperatorsClient for the given RESTClient. +func New(c rest.Interface) *OperatorsClient { + return &OperatorsClient{c} +} + +func setConfigDefaults(config *rest.Config) error { + config.APIPath = "/apis" + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } + if config.GroupVersion == nil || config.GroupVersion.Group != scheme.Scheme.PrioritizedVersionsForGroup("operators.coreos.com")[0].Group { + gv := scheme.Scheme.PrioritizedVersionsForGroup("operators.coreos.com")[0] + config.GroupVersion = &gv + } + config.NegotiatedSerializer = scheme.Codecs + + if config.QPS == 0 { + config.QPS = 5 + } + if config.Burst == 0 { + config.Burst = 10 + } + + return nil +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *OperatorsClient) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/operators/internalversion/packagemanifest.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/operators/internalversion/packagemanifest.go new file mode 100644 index 0000000000..e871c35e68 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/typed/operators/internalversion/packagemanifest.go @@ -0,0 +1,174 @@ +/* +Copyright 2019 Red Hat, 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 client-gen. DO NOT EDIT. + +package internalversion + +import ( + operators "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators" + scheme "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion/scheme" + v1 "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" +) + +// PackageManifestsGetter has a method to return a PackageManifestInterface. +// A group's client should implement this interface. +type PackageManifestsGetter interface { + PackageManifests(namespace string) PackageManifestInterface +} + +// PackageManifestInterface has methods to work with PackageManifest resources. +type PackageManifestInterface interface { + Create(*operators.PackageManifest) (*operators.PackageManifest, error) + Update(*operators.PackageManifest) (*operators.PackageManifest, error) + UpdateStatus(*operators.PackageManifest) (*operators.PackageManifest, error) + Delete(name string, options *v1.DeleteOptions) error + DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error + Get(name string, options v1.GetOptions) (*operators.PackageManifest, error) + List(opts v1.ListOptions) (*operators.PackageManifestList, error) + Watch(opts v1.ListOptions) (watch.Interface, error) + Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *operators.PackageManifest, err error) + PackageManifestExpansion +} + +// packageManifests implements PackageManifestInterface +type packageManifests struct { + client rest.Interface + ns string +} + +// newPackageManifests returns a PackageManifests +func newPackageManifests(c *OperatorsClient, namespace string) *packageManifests { + return &packageManifests{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the packageManifest, and returns the corresponding packageManifest object, and an error if there is any. +func (c *packageManifests) Get(name string, options v1.GetOptions) (result *operators.PackageManifest, err error) { + result = &operators.PackageManifest{} + err = c.client.Get(). + Namespace(c.ns). + Resource("packagemanifests"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of PackageManifests that match those selectors. +func (c *packageManifests) List(opts v1.ListOptions) (result *operators.PackageManifestList, err error) { + result = &operators.PackageManifestList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("packagemanifests"). + VersionedParams(&opts, scheme.ParameterCodec). + Do(). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested packageManifests. +func (c *packageManifests) Watch(opts v1.ListOptions) (watch.Interface, error) { + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("packagemanifests"). + VersionedParams(&opts, scheme.ParameterCodec). + Watch() +} + +// Create takes the representation of a packageManifest and creates it. Returns the server's representation of the packageManifest, and an error, if there is any. +func (c *packageManifests) Create(packageManifest *operators.PackageManifest) (result *operators.PackageManifest, err error) { + result = &operators.PackageManifest{} + err = c.client.Post(). + Namespace(c.ns). + Resource("packagemanifests"). + Body(packageManifest). + Do(). + Into(result) + return +} + +// Update takes the representation of a packageManifest and updates it. Returns the server's representation of the packageManifest, and an error, if there is any. +func (c *packageManifests) Update(packageManifest *operators.PackageManifest) (result *operators.PackageManifest, err error) { + result = &operators.PackageManifest{} + err = c.client.Put(). + Namespace(c.ns). + Resource("packagemanifests"). + Name(packageManifest.Name). + Body(packageManifest). + Do(). + 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 *packageManifests) UpdateStatus(packageManifest *operators.PackageManifest) (result *operators.PackageManifest, err error) { + result = &operators.PackageManifest{} + err = c.client.Put(). + Namespace(c.ns). + Resource("packagemanifests"). + Name(packageManifest.Name). + SubResource("status"). + Body(packageManifest). + Do(). + Into(result) + return +} + +// Delete takes name of the packageManifest and deletes it. Returns an error if one occurs. +func (c *packageManifests) Delete(name string, options *v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("packagemanifests"). + Name(name). + Body(options). + Do(). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *packageManifests) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("packagemanifests"). + VersionedParams(&listOptions, scheme.ParameterCodec). + Body(options). + Do(). + Error() +} + +// Patch applies the patch and returns the patched packageManifest. +func (c *packageManifests) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *operators.PackageManifest, err error) { + result = &operators.PackageManifest{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("packagemanifests"). + SubResource(subresources...). + Name(name). + Body(data). + Do(). + Into(result) + return +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/clientset.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/clientset.go index 601d23f0e3..b2e6076392 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/clientset.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/clientset.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -19,7 +19,8 @@ limitations under the License. package versioned import ( - packagemanifestv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/packagemanifest/v1alpha1" + appsv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/apps/v1alpha1" + operatorsv1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/operators/v1" discovery "k8s.io/client-go/discovery" rest "k8s.io/client-go/rest" flowcontrol "k8s.io/client-go/util/flowcontrol" @@ -27,27 +28,42 @@ import ( type Interface interface { Discovery() discovery.DiscoveryInterface - PackagemanifestV1alpha1() packagemanifestv1alpha1.PackagemanifestV1alpha1Interface + AppsV1alpha1() appsv1alpha1.AppsV1alpha1Interface // Deprecated: please explicitly pick a version if possible. - Packagemanifest() packagemanifestv1alpha1.PackagemanifestV1alpha1Interface + Apps() appsv1alpha1.AppsV1alpha1Interface + OperatorsV1() operatorsv1.OperatorsV1Interface + // Deprecated: please explicitly pick a version if possible. + Operators() operatorsv1.OperatorsV1Interface } // Clientset contains the clients for groups. Each group has exactly one // version included in a Clientset. type Clientset struct { *discovery.DiscoveryClient - packagemanifestV1alpha1 *packagemanifestv1alpha1.PackagemanifestV1alpha1Client + appsV1alpha1 *appsv1alpha1.AppsV1alpha1Client + operatorsV1 *operatorsv1.OperatorsV1Client } -// PackagemanifestV1alpha1 retrieves the PackagemanifestV1alpha1Client -func (c *Clientset) PackagemanifestV1alpha1() packagemanifestv1alpha1.PackagemanifestV1alpha1Interface { - return c.packagemanifestV1alpha1 +// AppsV1alpha1 retrieves the AppsV1alpha1Client +func (c *Clientset) AppsV1alpha1() appsv1alpha1.AppsV1alpha1Interface { + return c.appsV1alpha1 } -// Deprecated: Packagemanifest retrieves the default version of PackagemanifestClient. +// Deprecated: Apps retrieves the default version of AppsClient. // Please explicitly pick a version. -func (c *Clientset) Packagemanifest() packagemanifestv1alpha1.PackagemanifestV1alpha1Interface { - return c.packagemanifestV1alpha1 +func (c *Clientset) Apps() appsv1alpha1.AppsV1alpha1Interface { + return c.appsV1alpha1 +} + +// OperatorsV1 retrieves the OperatorsV1Client +func (c *Clientset) OperatorsV1() operatorsv1.OperatorsV1Interface { + return c.operatorsV1 +} + +// Deprecated: Operators retrieves the default version of OperatorsClient. +// Please explicitly pick a version. +func (c *Clientset) Operators() operatorsv1.OperatorsV1Interface { + return c.operatorsV1 } // Discovery retrieves the DiscoveryClient @@ -66,7 +82,11 @@ func NewForConfig(c *rest.Config) (*Clientset, error) { } var cs Clientset var err error - cs.packagemanifestV1alpha1, err = packagemanifestv1alpha1.NewForConfig(&configShallowCopy) + cs.appsV1alpha1, err = appsv1alpha1.NewForConfig(&configShallowCopy) + if err != nil { + return nil, err + } + cs.operatorsV1, err = operatorsv1.NewForConfig(&configShallowCopy) if err != nil { return nil, err } @@ -82,7 +102,8 @@ func NewForConfig(c *rest.Config) (*Clientset, error) { // panics if there is an error in the config. func NewForConfigOrDie(c *rest.Config) *Clientset { var cs Clientset - cs.packagemanifestV1alpha1 = packagemanifestv1alpha1.NewForConfigOrDie(c) + cs.appsV1alpha1 = appsv1alpha1.NewForConfigOrDie(c) + cs.operatorsV1 = operatorsv1.NewForConfigOrDie(c) cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c) return &cs @@ -91,7 +112,8 @@ func NewForConfigOrDie(c *rest.Config) *Clientset { // New creates a new Clientset for the given RESTClient. func New(c rest.Interface) *Clientset { var cs Clientset - cs.packagemanifestV1alpha1 = packagemanifestv1alpha1.New(c) + cs.appsV1alpha1 = appsv1alpha1.New(c) + cs.operatorsV1 = operatorsv1.New(c) cs.DiscoveryClient = discovery.NewDiscoveryClient(c) return &cs diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/doc.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/doc.go index 41721ca52d..b51d8e686b 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/doc.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/doc.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/fake/clientset_generated.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/fake/clientset_generated.go index 67c32d5a9d..937deac728 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/fake/clientset_generated.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/fake/clientset_generated.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -20,8 +20,10 @@ package fake import ( clientset "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned" - packagemanifestv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/packagemanifest/v1alpha1" - fakepackagemanifestv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/packagemanifest/v1alpha1/fake" + appsv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/apps/v1alpha1" + fakeappsv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/apps/v1alpha1/fake" + operatorsv1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/operators/v1" + fakeoperatorsv1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/operators/v1/fake" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/watch" "k8s.io/client-go/discovery" @@ -71,12 +73,22 @@ func (c *Clientset) Discovery() discovery.DiscoveryInterface { var _ clientset.Interface = &Clientset{} -// PackagemanifestV1alpha1 retrieves the PackagemanifestV1alpha1Client -func (c *Clientset) PackagemanifestV1alpha1() packagemanifestv1alpha1.PackagemanifestV1alpha1Interface { - return &fakepackagemanifestv1alpha1.FakePackagemanifestV1alpha1{Fake: &c.Fake} +// AppsV1alpha1 retrieves the AppsV1alpha1Client +func (c *Clientset) AppsV1alpha1() appsv1alpha1.AppsV1alpha1Interface { + return &fakeappsv1alpha1.FakeAppsV1alpha1{Fake: &c.Fake} } -// Packagemanifest retrieves the PackagemanifestV1alpha1Client -func (c *Clientset) Packagemanifest() packagemanifestv1alpha1.PackagemanifestV1alpha1Interface { - return &fakepackagemanifestv1alpha1.FakePackagemanifestV1alpha1{Fake: &c.Fake} +// Apps retrieves the AppsV1alpha1Client +func (c *Clientset) Apps() appsv1alpha1.AppsV1alpha1Interface { + return &fakeappsv1alpha1.FakeAppsV1alpha1{Fake: &c.Fake} +} + +// OperatorsV1 retrieves the OperatorsV1Client +func (c *Clientset) OperatorsV1() operatorsv1.OperatorsV1Interface { + return &fakeoperatorsv1.FakeOperatorsV1{Fake: &c.Fake} +} + +// Operators retrieves the OperatorsV1Client +func (c *Clientset) Operators() operatorsv1.OperatorsV1Interface { + return &fakeoperatorsv1.FakeOperatorsV1{Fake: &c.Fake} } diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/fake/doc.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/fake/doc.go index 9b99e71670..ee22a9450f 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/fake/doc.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/fake/doc.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/fake/register.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/fake/register.go index fc306e470f..be8abde6b0 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/fake/register.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/fake/register.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -19,20 +19,21 @@ limitations under the License. package fake import ( - packagemanifestv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1" + appsv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1" + operatorsv1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/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) - -func init() { - v1.AddToGroupVersion(scheme, schema.GroupVersion{Version: "v1"}) - AddToScheme(scheme) +var localSchemeBuilder = runtime.SchemeBuilder{ + appsv1alpha1.AddToScheme, + operatorsv1.AddToScheme, } // AddToScheme adds all types of this clientset into the given scheme. This allows composition @@ -45,10 +46,13 @@ func init() { // ) // // kclientset, _ := kubernetes.NewForConfig(c) -// aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) +// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) // // After this, RawExtensions in Kubernetes types will serialize kube-aggregator types // correctly. -func AddToScheme(scheme *runtime.Scheme) { - packagemanifestv1alpha1.AddToScheme(scheme) +var AddToScheme = localSchemeBuilder.AddToScheme + +func init() { + v1.AddToGroupVersion(scheme, schema.GroupVersion{Version: "v1"}) + utilruntime.Must(AddToScheme(scheme)) } diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/scheme/doc.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/scheme/doc.go index 7dc3756168..25323d1083 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/scheme/doc.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/scheme/doc.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/scheme/register.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/scheme/register.go index 3d72f09fac..b0d4f1a21e 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/scheme/register.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/scheme/register.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -19,20 +19,21 @@ limitations under the License. package scheme import ( - packagemanifestv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1" + appsv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1" + operatorsv1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/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) - -func init() { - v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"}) - AddToScheme(Scheme) +var localSchemeBuilder = runtime.SchemeBuilder{ + appsv1alpha1.AddToScheme, + operatorsv1.AddToScheme, } // AddToScheme adds all types of this clientset into the given scheme. This allows composition @@ -45,10 +46,13 @@ func init() { // ) // // kclientset, _ := kubernetes.NewForConfig(c) -// aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) +// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) // // After this, RawExtensions in Kubernetes types will serialize kube-aggregator types // correctly. -func AddToScheme(scheme *runtime.Scheme) { - packagemanifestv1alpha1.AddToScheme(scheme) +var AddToScheme = localSchemeBuilder.AddToScheme + +func init() { + v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"}) + utilruntime.Must(AddToScheme(Scheme)) } diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/packagemanifest/v1alpha1/packagemanifest_client.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/apps/v1alpha1/apps_client.go similarity index 64% rename from vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/packagemanifest/v1alpha1/packagemanifest_client.go rename to vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/apps/v1alpha1/apps_client.go index 2effee5f43..0a83b86801 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/packagemanifest/v1alpha1/packagemanifest_client.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/apps/v1alpha1/apps_client.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -19,28 +19,28 @@ limitations under the License. package v1alpha1 import ( - v1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1" + v1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1" "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/scheme" serializer "k8s.io/apimachinery/pkg/runtime/serializer" rest "k8s.io/client-go/rest" ) -type PackagemanifestV1alpha1Interface interface { +type AppsV1alpha1Interface interface { RESTClient() rest.Interface PackageManifestsGetter } -// PackagemanifestV1alpha1Client is used to interact with features provided by the packagemanifest group. -type PackagemanifestV1alpha1Client struct { +// AppsV1alpha1Client is used to interact with features provided by the apps.redhat.com group. +type AppsV1alpha1Client struct { restClient rest.Interface } -func (c *PackagemanifestV1alpha1Client) PackageManifests(namespace string) PackageManifestInterface { +func (c *AppsV1alpha1Client) PackageManifests(namespace string) PackageManifestInterface { return newPackageManifests(c, namespace) } -// NewForConfig creates a new PackagemanifestV1alpha1Client for the given config. -func NewForConfig(c *rest.Config) (*PackagemanifestV1alpha1Client, error) { +// NewForConfig creates a new AppsV1alpha1Client for the given config. +func NewForConfig(c *rest.Config) (*AppsV1alpha1Client, error) { config := *c if err := setConfigDefaults(&config); err != nil { return nil, err @@ -49,12 +49,12 @@ func NewForConfig(c *rest.Config) (*PackagemanifestV1alpha1Client, error) { if err != nil { return nil, err } - return &PackagemanifestV1alpha1Client{client}, nil + return &AppsV1alpha1Client{client}, nil } -// NewForConfigOrDie creates a new PackagemanifestV1alpha1Client for the given config and +// NewForConfigOrDie creates a new AppsV1alpha1Client for the given config and // panics if there is an error in the config. -func NewForConfigOrDie(c *rest.Config) *PackagemanifestV1alpha1Client { +func NewForConfigOrDie(c *rest.Config) *AppsV1alpha1Client { client, err := NewForConfig(c) if err != nil { panic(err) @@ -62,9 +62,9 @@ func NewForConfigOrDie(c *rest.Config) *PackagemanifestV1alpha1Client { return client } -// New creates a new PackagemanifestV1alpha1Client for the given RESTClient. -func New(c rest.Interface) *PackagemanifestV1alpha1Client { - return &PackagemanifestV1alpha1Client{c} +// New creates a new AppsV1alpha1Client for the given RESTClient. +func New(c rest.Interface) *AppsV1alpha1Client { + return &AppsV1alpha1Client{c} } func setConfigDefaults(config *rest.Config) error { @@ -82,7 +82,7 @@ func setConfigDefaults(config *rest.Config) error { // RESTClient returns a RESTClient that is used to communicate // with API server by this client implementation. -func (c *PackagemanifestV1alpha1Client) RESTClient() rest.Interface { +func (c *AppsV1alpha1Client) RESTClient() rest.Interface { if c == nil { return nil } diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/packagemanifest/v1alpha1/doc.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/apps/v1alpha1/doc.go similarity index 95% rename from vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/packagemanifest/v1alpha1/doc.go rename to vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/apps/v1alpha1/doc.go index df51baa4d4..06a90bb0e0 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/packagemanifest/v1alpha1/doc.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/apps/v1alpha1/doc.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/apps/v1alpha1/fake/doc.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/apps/v1alpha1/fake/doc.go new file mode 100644 index 0000000000..da6f0eb8e5 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/apps/v1alpha1/fake/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2019 Red Hat, 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 client-gen. DO NOT EDIT. + +// Package fake has the automatically generated clients. +package fake diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/packagemanifest/v1alpha1/fake/fake_packagemanifest_client.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/apps/v1alpha1/fake/fake_apps_client.go similarity index 73% rename from vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/packagemanifest/v1alpha1/fake/fake_packagemanifest_client.go rename to vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/apps/v1alpha1/fake/fake_apps_client.go index d7ccfcbab0..2e595ee223 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/packagemanifest/v1alpha1/fake/fake_packagemanifest_client.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/apps/v1alpha1/fake/fake_apps_client.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -19,22 +19,22 @@ limitations under the License. package fake import ( - v1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/packagemanifest/v1alpha1" + v1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/apps/v1alpha1" rest "k8s.io/client-go/rest" testing "k8s.io/client-go/testing" ) -type FakePackagemanifestV1alpha1 struct { +type FakeAppsV1alpha1 struct { *testing.Fake } -func (c *FakePackagemanifestV1alpha1) PackageManifests(namespace string) v1alpha1.PackageManifestInterface { +func (c *FakeAppsV1alpha1) PackageManifests(namespace string) v1alpha1.PackageManifestInterface { return &FakePackageManifests{c, namespace} } // RESTClient returns a RESTClient that is used to communicate // with API server by this client implementation. -func (c *FakePackagemanifestV1alpha1) RESTClient() rest.Interface { +func (c *FakeAppsV1alpha1) RESTClient() rest.Interface { var ret *rest.RESTClient return ret } diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/packagemanifest/v1alpha1/fake/fake_packagemanifest.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/apps/v1alpha1/fake/fake_packagemanifest.go similarity index 94% rename from vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/packagemanifest/v1alpha1/fake/fake_packagemanifest.go rename to vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/apps/v1alpha1/fake/fake_packagemanifest.go index a61c340917..4103851694 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/packagemanifest/v1alpha1/fake/fake_packagemanifest.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/apps/v1alpha1/fake/fake_packagemanifest.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -19,7 +19,7 @@ limitations under the License. package fake import ( - v1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1" + v1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" schema "k8s.io/apimachinery/pkg/runtime/schema" @@ -30,13 +30,13 @@ import ( // FakePackageManifests implements PackageManifestInterface type FakePackageManifests struct { - Fake *FakePackagemanifestV1alpha1 + Fake *FakeAppsV1alpha1 ns string } -var packagemanifestsResource = schema.GroupVersionResource{Group: "packagemanifest", Version: "v1alpha1", Resource: "packagemanifests"} +var packagemanifestsResource = schema.GroupVersionResource{Group: "apps.redhat.com", Version: "v1alpha1", Resource: "packagemanifests"} -var packagemanifestsKind = schema.GroupVersionKind{Group: "packagemanifest", Version: "v1alpha1", Kind: "PackageManifest"} +var packagemanifestsKind = schema.GroupVersionKind{Group: "apps.redhat.com", Version: "v1alpha1", Kind: "PackageManifest"} // Get takes name of the packageManifest, and returns the corresponding packageManifest object, and an error if there is any. func (c *FakePackageManifests) Get(name string, options v1.GetOptions) (result *v1alpha1.PackageManifest, err error) { diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/packagemanifest/v1alpha1/generated_expansion.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/apps/v1alpha1/generated_expansion.go similarity index 94% rename from vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/packagemanifest/v1alpha1/generated_expansion.go rename to vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/apps/v1alpha1/generated_expansion.go index cb6e88be2b..0fc098da63 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/packagemanifest/v1alpha1/generated_expansion.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/apps/v1alpha1/generated_expansion.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/packagemanifest/v1alpha1/packagemanifest.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/apps/v1alpha1/packagemanifest.go similarity index 96% rename from vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/packagemanifest/v1alpha1/packagemanifest.go rename to vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/apps/v1alpha1/packagemanifest.go index 1314efee61..553be981f5 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/packagemanifest/v1alpha1/packagemanifest.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/apps/v1alpha1/packagemanifest.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -19,7 +19,7 @@ limitations under the License. package v1alpha1 import ( - v1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1" + v1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1" scheme "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/scheme" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" @@ -54,7 +54,7 @@ type packageManifests struct { } // newPackageManifests returns a PackageManifests -func newPackageManifests(c *PackagemanifestV1alpha1Client, namespace string) *packageManifests { +func newPackageManifests(c *AppsV1alpha1Client, namespace string) *packageManifests { return &packageManifests{ client: c.RESTClient(), ns: namespace, diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/operators/v1/doc.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/operators/v1/doc.go new file mode 100644 index 0000000000..00df41cd1f --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/operators/v1/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2019 Red Hat, 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 client-gen. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v1 diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/operators/v1/fake/doc.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/operators/v1/fake/doc.go new file mode 100644 index 0000000000..da6f0eb8e5 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/operators/v1/fake/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2019 Red Hat, 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 client-gen. DO NOT EDIT. + +// Package fake has the automatically generated clients. +package fake diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/operators/v1/fake/fake_operators_client.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/operators/v1/fake/fake_operators_client.go new file mode 100644 index 0000000000..497b8e2c59 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/operators/v1/fake/fake_operators_client.go @@ -0,0 +1,40 @@ +/* +Copyright 2019 Red Hat, 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 client-gen. DO NOT EDIT. + +package fake + +import ( + v1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/operators/v1" + rest "k8s.io/client-go/rest" + testing "k8s.io/client-go/testing" +) + +type FakeOperatorsV1 struct { + *testing.Fake +} + +func (c *FakeOperatorsV1) PackageManifests(namespace string) v1.PackageManifestInterface { + return &FakePackageManifests{c, namespace} +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *FakeOperatorsV1) RESTClient() rest.Interface { + var ret *rest.RESTClient + return ret +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/operators/v1/fake/fake_packagemanifest.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/operators/v1/fake/fake_packagemanifest.go new file mode 100644 index 0000000000..0e9b39791c --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/operators/v1/fake/fake_packagemanifest.go @@ -0,0 +1,140 @@ +/* +Copyright 2019 Red Hat, 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 client-gen. DO NOT EDIT. + +package fake + +import ( + operatorsv1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + schema "k8s.io/apimachinery/pkg/runtime/schema" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakePackageManifests implements PackageManifestInterface +type FakePackageManifests struct { + Fake *FakeOperatorsV1 + ns string +} + +var packagemanifestsResource = schema.GroupVersionResource{Group: "operators.coreos.com", Version: "v1", Resource: "packagemanifests"} + +var packagemanifestsKind = schema.GroupVersionKind{Group: "operators.coreos.com", Version: "v1", Kind: "PackageManifest"} + +// Get takes name of the packageManifest, and returns the corresponding packageManifest object, and an error if there is any. +func (c *FakePackageManifests) Get(name string, options v1.GetOptions) (result *operatorsv1.PackageManifest, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(packagemanifestsResource, c.ns, name), &operatorsv1.PackageManifest{}) + + if obj == nil { + return nil, err + } + return obj.(*operatorsv1.PackageManifest), err +} + +// List takes label and field selectors, and returns the list of PackageManifests that match those selectors. +func (c *FakePackageManifests) List(opts v1.ListOptions) (result *operatorsv1.PackageManifestList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(packagemanifestsResource, packagemanifestsKind, c.ns, opts), &operatorsv1.PackageManifestList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &operatorsv1.PackageManifestList{ListMeta: obj.(*operatorsv1.PackageManifestList).ListMeta} + for _, item := range obj.(*operatorsv1.PackageManifestList).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 packageManifests. +func (c *FakePackageManifests) Watch(opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(packagemanifestsResource, c.ns, opts)) + +} + +// Create takes the representation of a packageManifest and creates it. Returns the server's representation of the packageManifest, and an error, if there is any. +func (c *FakePackageManifests) Create(packageManifest *operatorsv1.PackageManifest) (result *operatorsv1.PackageManifest, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(packagemanifestsResource, c.ns, packageManifest), &operatorsv1.PackageManifest{}) + + if obj == nil { + return nil, err + } + return obj.(*operatorsv1.PackageManifest), err +} + +// Update takes the representation of a packageManifest and updates it. Returns the server's representation of the packageManifest, and an error, if there is any. +func (c *FakePackageManifests) Update(packageManifest *operatorsv1.PackageManifest) (result *operatorsv1.PackageManifest, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(packagemanifestsResource, c.ns, packageManifest), &operatorsv1.PackageManifest{}) + + if obj == nil { + return nil, err + } + return obj.(*operatorsv1.PackageManifest), 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 *FakePackageManifests) UpdateStatus(packageManifest *operatorsv1.PackageManifest) (*operatorsv1.PackageManifest, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(packagemanifestsResource, "status", c.ns, packageManifest), &operatorsv1.PackageManifest{}) + + if obj == nil { + return nil, err + } + return obj.(*operatorsv1.PackageManifest), err +} + +// Delete takes name of the packageManifest and deletes it. Returns an error if one occurs. +func (c *FakePackageManifests) Delete(name string, options *v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteAction(packagemanifestsResource, c.ns, name), &operatorsv1.PackageManifest{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakePackageManifests) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(packagemanifestsResource, c.ns, listOptions) + + _, err := c.Fake.Invokes(action, &operatorsv1.PackageManifestList{}) + return err +} + +// Patch applies the patch and returns the patched packageManifest. +func (c *FakePackageManifests) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *operatorsv1.PackageManifest, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(packagemanifestsResource, c.ns, name, data, subresources...), &operatorsv1.PackageManifest{}) + + if obj == nil { + return nil, err + } + return obj.(*operatorsv1.PackageManifest), err +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/operators/v1/generated_expansion.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/operators/v1/generated_expansion.go new file mode 100644 index 0000000000..eada72d93a --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/operators/v1/generated_expansion.go @@ -0,0 +1,21 @@ +/* +Copyright 2019 Red Hat, 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 client-gen. DO NOT EDIT. + +package v1 + +type PackageManifestExpansion interface{} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/operators/v1/operators_client.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/operators/v1/operators_client.go new file mode 100644 index 0000000000..710bae77f4 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/operators/v1/operators_client.go @@ -0,0 +1,90 @@ +/* +Copyright 2019 Red Hat, 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 client-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1" + "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/scheme" + serializer "k8s.io/apimachinery/pkg/runtime/serializer" + rest "k8s.io/client-go/rest" +) + +type OperatorsV1Interface interface { + RESTClient() rest.Interface + PackageManifestsGetter +} + +// OperatorsV1Client is used to interact with features provided by the operators.coreos.com group. +type OperatorsV1Client struct { + restClient rest.Interface +} + +func (c *OperatorsV1Client) PackageManifests(namespace string) PackageManifestInterface { + return newPackageManifests(c, namespace) +} + +// NewForConfig creates a new OperatorsV1Client for the given config. +func NewForConfig(c *rest.Config) (*OperatorsV1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientFor(&config) + if err != nil { + return nil, err + } + return &OperatorsV1Client{client}, nil +} + +// NewForConfigOrDie creates a new OperatorsV1Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *OperatorsV1Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new OperatorsV1Client for the given RESTClient. +func New(c rest.Interface) *OperatorsV1Client { + return &OperatorsV1Client{c} +} + +func setConfigDefaults(config *rest.Config) error { + gv := v1.SchemeGroupVersion + config.GroupVersion = &gv + config.APIPath = "/apis" + config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: scheme.Codecs} + + 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 *OperatorsV1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/operators/v1/packagemanifest.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/operators/v1/packagemanifest.go new file mode 100644 index 0000000000..ff0c326d92 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned/typed/operators/v1/packagemanifest.go @@ -0,0 +1,174 @@ +/* +Copyright 2019 Red Hat, 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 client-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1" + scheme "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/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" +) + +// PackageManifestsGetter has a method to return a PackageManifestInterface. +// A group's client should implement this interface. +type PackageManifestsGetter interface { + PackageManifests(namespace string) PackageManifestInterface +} + +// PackageManifestInterface has methods to work with PackageManifest resources. +type PackageManifestInterface interface { + Create(*v1.PackageManifest) (*v1.PackageManifest, error) + Update(*v1.PackageManifest) (*v1.PackageManifest, error) + UpdateStatus(*v1.PackageManifest) (*v1.PackageManifest, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteCollection(options *metav1.DeleteOptions, listOptions metav1.ListOptions) error + Get(name string, options metav1.GetOptions) (*v1.PackageManifest, error) + List(opts metav1.ListOptions) (*v1.PackageManifestList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1.PackageManifest, err error) + PackageManifestExpansion +} + +// packageManifests implements PackageManifestInterface +type packageManifests struct { + client rest.Interface + ns string +} + +// newPackageManifests returns a PackageManifests +func newPackageManifests(c *OperatorsV1Client, namespace string) *packageManifests { + return &packageManifests{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the packageManifest, and returns the corresponding packageManifest object, and an error if there is any. +func (c *packageManifests) Get(name string, options metav1.GetOptions) (result *v1.PackageManifest, err error) { + result = &v1.PackageManifest{} + err = c.client.Get(). + Namespace(c.ns). + Resource("packagemanifests"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of PackageManifests that match those selectors. +func (c *packageManifests) List(opts metav1.ListOptions) (result *v1.PackageManifestList, err error) { + result = &v1.PackageManifestList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("packagemanifests"). + VersionedParams(&opts, scheme.ParameterCodec). + Do(). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested packageManifests. +func (c *packageManifests) Watch(opts metav1.ListOptions) (watch.Interface, error) { + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("packagemanifests"). + VersionedParams(&opts, scheme.ParameterCodec). + Watch() +} + +// Create takes the representation of a packageManifest and creates it. Returns the server's representation of the packageManifest, and an error, if there is any. +func (c *packageManifests) Create(packageManifest *v1.PackageManifest) (result *v1.PackageManifest, err error) { + result = &v1.PackageManifest{} + err = c.client.Post(). + Namespace(c.ns). + Resource("packagemanifests"). + Body(packageManifest). + Do(). + Into(result) + return +} + +// Update takes the representation of a packageManifest and updates it. Returns the server's representation of the packageManifest, and an error, if there is any. +func (c *packageManifests) Update(packageManifest *v1.PackageManifest) (result *v1.PackageManifest, err error) { + result = &v1.PackageManifest{} + err = c.client.Put(). + Namespace(c.ns). + Resource("packagemanifests"). + Name(packageManifest.Name). + Body(packageManifest). + Do(). + 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 *packageManifests) UpdateStatus(packageManifest *v1.PackageManifest) (result *v1.PackageManifest, err error) { + result = &v1.PackageManifest{} + err = c.client.Put(). + Namespace(c.ns). + Resource("packagemanifests"). + Name(packageManifest.Name). + SubResource("status"). + Body(packageManifest). + Do(). + Into(result) + return +} + +// Delete takes name of the packageManifest and deletes it. Returns an error if one occurs. +func (c *packageManifests) Delete(name string, options *metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("packagemanifests"). + Name(name). + Body(options). + Do(). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *packageManifests) DeleteCollection(options *metav1.DeleteOptions, listOptions metav1.ListOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("packagemanifests"). + VersionedParams(&listOptions, scheme.ParameterCodec). + Body(options). + Do(). + Error() +} + +// Patch applies the patch and returns the patched packageManifest. +func (c *packageManifests) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1.PackageManifest, err error) { + result = &v1.PackageManifest{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("packagemanifests"). + SubResource(subresources...). + Name(name). + Body(data). + Do(). + Into(result) + return +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/fakes/fake_registry_client.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/fakes/fake_registry_client.go new file mode 100644 index 0000000000..0e17307d0d --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/fakes/fake_registry_client.go @@ -0,0 +1,777 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package fakes + +import ( + context "context" + sync "sync" + + api "github.com/operator-framework/operator-registry/pkg/api" + grpc "google.golang.org/grpc" +) + +type FakeRegistryClient struct { + GetBundleStub func(context.Context, *api.GetBundleRequest, ...grpc.CallOption) (*api.Bundle, error) + getBundleMutex sync.RWMutex + getBundleArgsForCall []struct { + arg1 context.Context + arg2 *api.GetBundleRequest + arg3 []grpc.CallOption + } + getBundleReturns struct { + result1 *api.Bundle + result2 error + } + getBundleReturnsOnCall map[int]struct { + result1 *api.Bundle + result2 error + } + GetBundleForChannelStub func(context.Context, *api.GetBundleInChannelRequest, ...grpc.CallOption) (*api.Bundle, error) + getBundleForChannelMutex sync.RWMutex + getBundleForChannelArgsForCall []struct { + arg1 context.Context + arg2 *api.GetBundleInChannelRequest + arg3 []grpc.CallOption + } + getBundleForChannelReturns struct { + result1 *api.Bundle + result2 error + } + getBundleForChannelReturnsOnCall map[int]struct { + result1 *api.Bundle + result2 error + } + GetBundleThatReplacesStub func(context.Context, *api.GetReplacementRequest, ...grpc.CallOption) (*api.Bundle, error) + getBundleThatReplacesMutex sync.RWMutex + getBundleThatReplacesArgsForCall []struct { + arg1 context.Context + arg2 *api.GetReplacementRequest + arg3 []grpc.CallOption + } + getBundleThatReplacesReturns struct { + result1 *api.Bundle + result2 error + } + getBundleThatReplacesReturnsOnCall map[int]struct { + result1 *api.Bundle + result2 error + } + GetChannelEntriesThatProvideStub func(context.Context, *api.GetAllProvidersRequest, ...grpc.CallOption) (api.Registry_GetChannelEntriesThatProvideClient, error) + getChannelEntriesThatProvideMutex sync.RWMutex + getChannelEntriesThatProvideArgsForCall []struct { + arg1 context.Context + arg2 *api.GetAllProvidersRequest + arg3 []grpc.CallOption + } + getChannelEntriesThatProvideReturns struct { + result1 api.Registry_GetChannelEntriesThatProvideClient + result2 error + } + getChannelEntriesThatProvideReturnsOnCall map[int]struct { + result1 api.Registry_GetChannelEntriesThatProvideClient + result2 error + } + GetChannelEntriesThatReplaceStub func(context.Context, *api.GetAllReplacementsRequest, ...grpc.CallOption) (api.Registry_GetChannelEntriesThatReplaceClient, error) + getChannelEntriesThatReplaceMutex sync.RWMutex + getChannelEntriesThatReplaceArgsForCall []struct { + arg1 context.Context + arg2 *api.GetAllReplacementsRequest + arg3 []grpc.CallOption + } + getChannelEntriesThatReplaceReturns struct { + result1 api.Registry_GetChannelEntriesThatReplaceClient + result2 error + } + getChannelEntriesThatReplaceReturnsOnCall map[int]struct { + result1 api.Registry_GetChannelEntriesThatReplaceClient + result2 error + } + GetDefaultBundleThatProvidesStub func(context.Context, *api.GetDefaultProviderRequest, ...grpc.CallOption) (*api.Bundle, error) + getDefaultBundleThatProvidesMutex sync.RWMutex + getDefaultBundleThatProvidesArgsForCall []struct { + arg1 context.Context + arg2 *api.GetDefaultProviderRequest + arg3 []grpc.CallOption + } + getDefaultBundleThatProvidesReturns struct { + result1 *api.Bundle + result2 error + } + getDefaultBundleThatProvidesReturnsOnCall map[int]struct { + result1 *api.Bundle + result2 error + } + GetLatestChannelEntriesThatProvideStub func(context.Context, *api.GetLatestProvidersRequest, ...grpc.CallOption) (api.Registry_GetLatestChannelEntriesThatProvideClient, error) + getLatestChannelEntriesThatProvideMutex sync.RWMutex + getLatestChannelEntriesThatProvideArgsForCall []struct { + arg1 context.Context + arg2 *api.GetLatestProvidersRequest + arg3 []grpc.CallOption + } + getLatestChannelEntriesThatProvideReturns struct { + result1 api.Registry_GetLatestChannelEntriesThatProvideClient + result2 error + } + getLatestChannelEntriesThatProvideReturnsOnCall map[int]struct { + result1 api.Registry_GetLatestChannelEntriesThatProvideClient + result2 error + } + GetPackageStub func(context.Context, *api.GetPackageRequest, ...grpc.CallOption) (*api.Package, error) + getPackageMutex sync.RWMutex + getPackageArgsForCall []struct { + arg1 context.Context + arg2 *api.GetPackageRequest + arg3 []grpc.CallOption + } + getPackageReturns struct { + result1 *api.Package + result2 error + } + getPackageReturnsOnCall map[int]struct { + result1 *api.Package + result2 error + } + ListPackagesStub func(context.Context, *api.ListPackageRequest, ...grpc.CallOption) (api.Registry_ListPackagesClient, error) + listPackagesMutex sync.RWMutex + listPackagesArgsForCall []struct { + arg1 context.Context + arg2 *api.ListPackageRequest + arg3 []grpc.CallOption + } + listPackagesReturns struct { + result1 api.Registry_ListPackagesClient + result2 error + } + listPackagesReturnsOnCall map[int]struct { + result1 api.Registry_ListPackagesClient + result2 error + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *FakeRegistryClient) GetBundle(arg1 context.Context, arg2 *api.GetBundleRequest, arg3 ...grpc.CallOption) (*api.Bundle, error) { + fake.getBundleMutex.Lock() + ret, specificReturn := fake.getBundleReturnsOnCall[len(fake.getBundleArgsForCall)] + fake.getBundleArgsForCall = append(fake.getBundleArgsForCall, struct { + arg1 context.Context + arg2 *api.GetBundleRequest + arg3 []grpc.CallOption + }{arg1, arg2, arg3}) + fake.recordInvocation("GetBundle", []interface{}{arg1, arg2, arg3}) + fake.getBundleMutex.Unlock() + if fake.GetBundleStub != nil { + return fake.GetBundleStub(arg1, arg2, arg3...) + } + if specificReturn { + return ret.result1, ret.result2 + } + fakeReturns := fake.getBundleReturns + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *FakeRegistryClient) GetBundleCallCount() int { + fake.getBundleMutex.RLock() + defer fake.getBundleMutex.RUnlock() + return len(fake.getBundleArgsForCall) +} + +func (fake *FakeRegistryClient) GetBundleCalls(stub func(context.Context, *api.GetBundleRequest, ...grpc.CallOption) (*api.Bundle, error)) { + fake.getBundleMutex.Lock() + defer fake.getBundleMutex.Unlock() + fake.GetBundleStub = stub +} + +func (fake *FakeRegistryClient) GetBundleArgsForCall(i int) (context.Context, *api.GetBundleRequest, []grpc.CallOption) { + fake.getBundleMutex.RLock() + defer fake.getBundleMutex.RUnlock() + argsForCall := fake.getBundleArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3 +} + +func (fake *FakeRegistryClient) GetBundleReturns(result1 *api.Bundle, result2 error) { + fake.getBundleMutex.Lock() + defer fake.getBundleMutex.Unlock() + fake.GetBundleStub = nil + fake.getBundleReturns = struct { + result1 *api.Bundle + result2 error + }{result1, result2} +} + +func (fake *FakeRegistryClient) GetBundleReturnsOnCall(i int, result1 *api.Bundle, result2 error) { + fake.getBundleMutex.Lock() + defer fake.getBundleMutex.Unlock() + fake.GetBundleStub = nil + if fake.getBundleReturnsOnCall == nil { + fake.getBundleReturnsOnCall = make(map[int]struct { + result1 *api.Bundle + result2 error + }) + } + fake.getBundleReturnsOnCall[i] = struct { + result1 *api.Bundle + result2 error + }{result1, result2} +} + +func (fake *FakeRegistryClient) GetBundleForChannel(arg1 context.Context, arg2 *api.GetBundleInChannelRequest, arg3 ...grpc.CallOption) (*api.Bundle, error) { + fake.getBundleForChannelMutex.Lock() + ret, specificReturn := fake.getBundleForChannelReturnsOnCall[len(fake.getBundleForChannelArgsForCall)] + fake.getBundleForChannelArgsForCall = append(fake.getBundleForChannelArgsForCall, struct { + arg1 context.Context + arg2 *api.GetBundleInChannelRequest + arg3 []grpc.CallOption + }{arg1, arg2, arg3}) + fake.recordInvocation("GetBundleForChannel", []interface{}{arg1, arg2, arg3}) + fake.getBundleForChannelMutex.Unlock() + if fake.GetBundleForChannelStub != nil { + return fake.GetBundleForChannelStub(arg1, arg2, arg3...) + } + if specificReturn { + return ret.result1, ret.result2 + } + fakeReturns := fake.getBundleForChannelReturns + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *FakeRegistryClient) GetBundleForChannelCallCount() int { + fake.getBundleForChannelMutex.RLock() + defer fake.getBundleForChannelMutex.RUnlock() + return len(fake.getBundleForChannelArgsForCall) +} + +func (fake *FakeRegistryClient) GetBundleForChannelCalls(stub func(context.Context, *api.GetBundleInChannelRequest, ...grpc.CallOption) (*api.Bundle, error)) { + fake.getBundleForChannelMutex.Lock() + defer fake.getBundleForChannelMutex.Unlock() + fake.GetBundleForChannelStub = stub +} + +func (fake *FakeRegistryClient) GetBundleForChannelArgsForCall(i int) (context.Context, *api.GetBundleInChannelRequest, []grpc.CallOption) { + fake.getBundleForChannelMutex.RLock() + defer fake.getBundleForChannelMutex.RUnlock() + argsForCall := fake.getBundleForChannelArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3 +} + +func (fake *FakeRegistryClient) GetBundleForChannelReturns(result1 *api.Bundle, result2 error) { + fake.getBundleForChannelMutex.Lock() + defer fake.getBundleForChannelMutex.Unlock() + fake.GetBundleForChannelStub = nil + fake.getBundleForChannelReturns = struct { + result1 *api.Bundle + result2 error + }{result1, result2} +} + +func (fake *FakeRegistryClient) GetBundleForChannelReturnsOnCall(i int, result1 *api.Bundle, result2 error) { + fake.getBundleForChannelMutex.Lock() + defer fake.getBundleForChannelMutex.Unlock() + fake.GetBundleForChannelStub = nil + if fake.getBundleForChannelReturnsOnCall == nil { + fake.getBundleForChannelReturnsOnCall = make(map[int]struct { + result1 *api.Bundle + result2 error + }) + } + fake.getBundleForChannelReturnsOnCall[i] = struct { + result1 *api.Bundle + result2 error + }{result1, result2} +} + +func (fake *FakeRegistryClient) GetBundleThatReplaces(arg1 context.Context, arg2 *api.GetReplacementRequest, arg3 ...grpc.CallOption) (*api.Bundle, error) { + fake.getBundleThatReplacesMutex.Lock() + ret, specificReturn := fake.getBundleThatReplacesReturnsOnCall[len(fake.getBundleThatReplacesArgsForCall)] + fake.getBundleThatReplacesArgsForCall = append(fake.getBundleThatReplacesArgsForCall, struct { + arg1 context.Context + arg2 *api.GetReplacementRequest + arg3 []grpc.CallOption + }{arg1, arg2, arg3}) + fake.recordInvocation("GetBundleThatReplaces", []interface{}{arg1, arg2, arg3}) + fake.getBundleThatReplacesMutex.Unlock() + if fake.GetBundleThatReplacesStub != nil { + return fake.GetBundleThatReplacesStub(arg1, arg2, arg3...) + } + if specificReturn { + return ret.result1, ret.result2 + } + fakeReturns := fake.getBundleThatReplacesReturns + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *FakeRegistryClient) GetBundleThatReplacesCallCount() int { + fake.getBundleThatReplacesMutex.RLock() + defer fake.getBundleThatReplacesMutex.RUnlock() + return len(fake.getBundleThatReplacesArgsForCall) +} + +func (fake *FakeRegistryClient) GetBundleThatReplacesCalls(stub func(context.Context, *api.GetReplacementRequest, ...grpc.CallOption) (*api.Bundle, error)) { + fake.getBundleThatReplacesMutex.Lock() + defer fake.getBundleThatReplacesMutex.Unlock() + fake.GetBundleThatReplacesStub = stub +} + +func (fake *FakeRegistryClient) GetBundleThatReplacesArgsForCall(i int) (context.Context, *api.GetReplacementRequest, []grpc.CallOption) { + fake.getBundleThatReplacesMutex.RLock() + defer fake.getBundleThatReplacesMutex.RUnlock() + argsForCall := fake.getBundleThatReplacesArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3 +} + +func (fake *FakeRegistryClient) GetBundleThatReplacesReturns(result1 *api.Bundle, result2 error) { + fake.getBundleThatReplacesMutex.Lock() + defer fake.getBundleThatReplacesMutex.Unlock() + fake.GetBundleThatReplacesStub = nil + fake.getBundleThatReplacesReturns = struct { + result1 *api.Bundle + result2 error + }{result1, result2} +} + +func (fake *FakeRegistryClient) GetBundleThatReplacesReturnsOnCall(i int, result1 *api.Bundle, result2 error) { + fake.getBundleThatReplacesMutex.Lock() + defer fake.getBundleThatReplacesMutex.Unlock() + fake.GetBundleThatReplacesStub = nil + if fake.getBundleThatReplacesReturnsOnCall == nil { + fake.getBundleThatReplacesReturnsOnCall = make(map[int]struct { + result1 *api.Bundle + result2 error + }) + } + fake.getBundleThatReplacesReturnsOnCall[i] = struct { + result1 *api.Bundle + result2 error + }{result1, result2} +} + +func (fake *FakeRegistryClient) GetChannelEntriesThatProvide(arg1 context.Context, arg2 *api.GetAllProvidersRequest, arg3 ...grpc.CallOption) (api.Registry_GetChannelEntriesThatProvideClient, error) { + fake.getChannelEntriesThatProvideMutex.Lock() + ret, specificReturn := fake.getChannelEntriesThatProvideReturnsOnCall[len(fake.getChannelEntriesThatProvideArgsForCall)] + fake.getChannelEntriesThatProvideArgsForCall = append(fake.getChannelEntriesThatProvideArgsForCall, struct { + arg1 context.Context + arg2 *api.GetAllProvidersRequest + arg3 []grpc.CallOption + }{arg1, arg2, arg3}) + fake.recordInvocation("GetChannelEntriesThatProvide", []interface{}{arg1, arg2, arg3}) + fake.getChannelEntriesThatProvideMutex.Unlock() + if fake.GetChannelEntriesThatProvideStub != nil { + return fake.GetChannelEntriesThatProvideStub(arg1, arg2, arg3...) + } + if specificReturn { + return ret.result1, ret.result2 + } + fakeReturns := fake.getChannelEntriesThatProvideReturns + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *FakeRegistryClient) GetChannelEntriesThatProvideCallCount() int { + fake.getChannelEntriesThatProvideMutex.RLock() + defer fake.getChannelEntriesThatProvideMutex.RUnlock() + return len(fake.getChannelEntriesThatProvideArgsForCall) +} + +func (fake *FakeRegistryClient) GetChannelEntriesThatProvideCalls(stub func(context.Context, *api.GetAllProvidersRequest, ...grpc.CallOption) (api.Registry_GetChannelEntriesThatProvideClient, error)) { + fake.getChannelEntriesThatProvideMutex.Lock() + defer fake.getChannelEntriesThatProvideMutex.Unlock() + fake.GetChannelEntriesThatProvideStub = stub +} + +func (fake *FakeRegistryClient) GetChannelEntriesThatProvideArgsForCall(i int) (context.Context, *api.GetAllProvidersRequest, []grpc.CallOption) { + fake.getChannelEntriesThatProvideMutex.RLock() + defer fake.getChannelEntriesThatProvideMutex.RUnlock() + argsForCall := fake.getChannelEntriesThatProvideArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3 +} + +func (fake *FakeRegistryClient) GetChannelEntriesThatProvideReturns(result1 api.Registry_GetChannelEntriesThatProvideClient, result2 error) { + fake.getChannelEntriesThatProvideMutex.Lock() + defer fake.getChannelEntriesThatProvideMutex.Unlock() + fake.GetChannelEntriesThatProvideStub = nil + fake.getChannelEntriesThatProvideReturns = struct { + result1 api.Registry_GetChannelEntriesThatProvideClient + result2 error + }{result1, result2} +} + +func (fake *FakeRegistryClient) GetChannelEntriesThatProvideReturnsOnCall(i int, result1 api.Registry_GetChannelEntriesThatProvideClient, result2 error) { + fake.getChannelEntriesThatProvideMutex.Lock() + defer fake.getChannelEntriesThatProvideMutex.Unlock() + fake.GetChannelEntriesThatProvideStub = nil + if fake.getChannelEntriesThatProvideReturnsOnCall == nil { + fake.getChannelEntriesThatProvideReturnsOnCall = make(map[int]struct { + result1 api.Registry_GetChannelEntriesThatProvideClient + result2 error + }) + } + fake.getChannelEntriesThatProvideReturnsOnCall[i] = struct { + result1 api.Registry_GetChannelEntriesThatProvideClient + result2 error + }{result1, result2} +} + +func (fake *FakeRegistryClient) GetChannelEntriesThatReplace(arg1 context.Context, arg2 *api.GetAllReplacementsRequest, arg3 ...grpc.CallOption) (api.Registry_GetChannelEntriesThatReplaceClient, error) { + fake.getChannelEntriesThatReplaceMutex.Lock() + ret, specificReturn := fake.getChannelEntriesThatReplaceReturnsOnCall[len(fake.getChannelEntriesThatReplaceArgsForCall)] + fake.getChannelEntriesThatReplaceArgsForCall = append(fake.getChannelEntriesThatReplaceArgsForCall, struct { + arg1 context.Context + arg2 *api.GetAllReplacementsRequest + arg3 []grpc.CallOption + }{arg1, arg2, arg3}) + fake.recordInvocation("GetChannelEntriesThatReplace", []interface{}{arg1, arg2, arg3}) + fake.getChannelEntriesThatReplaceMutex.Unlock() + if fake.GetChannelEntriesThatReplaceStub != nil { + return fake.GetChannelEntriesThatReplaceStub(arg1, arg2, arg3...) + } + if specificReturn { + return ret.result1, ret.result2 + } + fakeReturns := fake.getChannelEntriesThatReplaceReturns + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *FakeRegistryClient) GetChannelEntriesThatReplaceCallCount() int { + fake.getChannelEntriesThatReplaceMutex.RLock() + defer fake.getChannelEntriesThatReplaceMutex.RUnlock() + return len(fake.getChannelEntriesThatReplaceArgsForCall) +} + +func (fake *FakeRegistryClient) GetChannelEntriesThatReplaceCalls(stub func(context.Context, *api.GetAllReplacementsRequest, ...grpc.CallOption) (api.Registry_GetChannelEntriesThatReplaceClient, error)) { + fake.getChannelEntriesThatReplaceMutex.Lock() + defer fake.getChannelEntriesThatReplaceMutex.Unlock() + fake.GetChannelEntriesThatReplaceStub = stub +} + +func (fake *FakeRegistryClient) GetChannelEntriesThatReplaceArgsForCall(i int) (context.Context, *api.GetAllReplacementsRequest, []grpc.CallOption) { + fake.getChannelEntriesThatReplaceMutex.RLock() + defer fake.getChannelEntriesThatReplaceMutex.RUnlock() + argsForCall := fake.getChannelEntriesThatReplaceArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3 +} + +func (fake *FakeRegistryClient) GetChannelEntriesThatReplaceReturns(result1 api.Registry_GetChannelEntriesThatReplaceClient, result2 error) { + fake.getChannelEntriesThatReplaceMutex.Lock() + defer fake.getChannelEntriesThatReplaceMutex.Unlock() + fake.GetChannelEntriesThatReplaceStub = nil + fake.getChannelEntriesThatReplaceReturns = struct { + result1 api.Registry_GetChannelEntriesThatReplaceClient + result2 error + }{result1, result2} +} + +func (fake *FakeRegistryClient) GetChannelEntriesThatReplaceReturnsOnCall(i int, result1 api.Registry_GetChannelEntriesThatReplaceClient, result2 error) { + fake.getChannelEntriesThatReplaceMutex.Lock() + defer fake.getChannelEntriesThatReplaceMutex.Unlock() + fake.GetChannelEntriesThatReplaceStub = nil + if fake.getChannelEntriesThatReplaceReturnsOnCall == nil { + fake.getChannelEntriesThatReplaceReturnsOnCall = make(map[int]struct { + result1 api.Registry_GetChannelEntriesThatReplaceClient + result2 error + }) + } + fake.getChannelEntriesThatReplaceReturnsOnCall[i] = struct { + result1 api.Registry_GetChannelEntriesThatReplaceClient + result2 error + }{result1, result2} +} + +func (fake *FakeRegistryClient) GetDefaultBundleThatProvides(arg1 context.Context, arg2 *api.GetDefaultProviderRequest, arg3 ...grpc.CallOption) (*api.Bundle, error) { + fake.getDefaultBundleThatProvidesMutex.Lock() + ret, specificReturn := fake.getDefaultBundleThatProvidesReturnsOnCall[len(fake.getDefaultBundleThatProvidesArgsForCall)] + fake.getDefaultBundleThatProvidesArgsForCall = append(fake.getDefaultBundleThatProvidesArgsForCall, struct { + arg1 context.Context + arg2 *api.GetDefaultProviderRequest + arg3 []grpc.CallOption + }{arg1, arg2, arg3}) + fake.recordInvocation("GetDefaultBundleThatProvides", []interface{}{arg1, arg2, arg3}) + fake.getDefaultBundleThatProvidesMutex.Unlock() + if fake.GetDefaultBundleThatProvidesStub != nil { + return fake.GetDefaultBundleThatProvidesStub(arg1, arg2, arg3...) + } + if specificReturn { + return ret.result1, ret.result2 + } + fakeReturns := fake.getDefaultBundleThatProvidesReturns + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *FakeRegistryClient) GetDefaultBundleThatProvidesCallCount() int { + fake.getDefaultBundleThatProvidesMutex.RLock() + defer fake.getDefaultBundleThatProvidesMutex.RUnlock() + return len(fake.getDefaultBundleThatProvidesArgsForCall) +} + +func (fake *FakeRegistryClient) GetDefaultBundleThatProvidesCalls(stub func(context.Context, *api.GetDefaultProviderRequest, ...grpc.CallOption) (*api.Bundle, error)) { + fake.getDefaultBundleThatProvidesMutex.Lock() + defer fake.getDefaultBundleThatProvidesMutex.Unlock() + fake.GetDefaultBundleThatProvidesStub = stub +} + +func (fake *FakeRegistryClient) GetDefaultBundleThatProvidesArgsForCall(i int) (context.Context, *api.GetDefaultProviderRequest, []grpc.CallOption) { + fake.getDefaultBundleThatProvidesMutex.RLock() + defer fake.getDefaultBundleThatProvidesMutex.RUnlock() + argsForCall := fake.getDefaultBundleThatProvidesArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3 +} + +func (fake *FakeRegistryClient) GetDefaultBundleThatProvidesReturns(result1 *api.Bundle, result2 error) { + fake.getDefaultBundleThatProvidesMutex.Lock() + defer fake.getDefaultBundleThatProvidesMutex.Unlock() + fake.GetDefaultBundleThatProvidesStub = nil + fake.getDefaultBundleThatProvidesReturns = struct { + result1 *api.Bundle + result2 error + }{result1, result2} +} + +func (fake *FakeRegistryClient) GetDefaultBundleThatProvidesReturnsOnCall(i int, result1 *api.Bundle, result2 error) { + fake.getDefaultBundleThatProvidesMutex.Lock() + defer fake.getDefaultBundleThatProvidesMutex.Unlock() + fake.GetDefaultBundleThatProvidesStub = nil + if fake.getDefaultBundleThatProvidesReturnsOnCall == nil { + fake.getDefaultBundleThatProvidesReturnsOnCall = make(map[int]struct { + result1 *api.Bundle + result2 error + }) + } + fake.getDefaultBundleThatProvidesReturnsOnCall[i] = struct { + result1 *api.Bundle + result2 error + }{result1, result2} +} + +func (fake *FakeRegistryClient) GetLatestChannelEntriesThatProvide(arg1 context.Context, arg2 *api.GetLatestProvidersRequest, arg3 ...grpc.CallOption) (api.Registry_GetLatestChannelEntriesThatProvideClient, error) { + fake.getLatestChannelEntriesThatProvideMutex.Lock() + ret, specificReturn := fake.getLatestChannelEntriesThatProvideReturnsOnCall[len(fake.getLatestChannelEntriesThatProvideArgsForCall)] + fake.getLatestChannelEntriesThatProvideArgsForCall = append(fake.getLatestChannelEntriesThatProvideArgsForCall, struct { + arg1 context.Context + arg2 *api.GetLatestProvidersRequest + arg3 []grpc.CallOption + }{arg1, arg2, arg3}) + fake.recordInvocation("GetLatestChannelEntriesThatProvide", []interface{}{arg1, arg2, arg3}) + fake.getLatestChannelEntriesThatProvideMutex.Unlock() + if fake.GetLatestChannelEntriesThatProvideStub != nil { + return fake.GetLatestChannelEntriesThatProvideStub(arg1, arg2, arg3...) + } + if specificReturn { + return ret.result1, ret.result2 + } + fakeReturns := fake.getLatestChannelEntriesThatProvideReturns + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *FakeRegistryClient) GetLatestChannelEntriesThatProvideCallCount() int { + fake.getLatestChannelEntriesThatProvideMutex.RLock() + defer fake.getLatestChannelEntriesThatProvideMutex.RUnlock() + return len(fake.getLatestChannelEntriesThatProvideArgsForCall) +} + +func (fake *FakeRegistryClient) GetLatestChannelEntriesThatProvideCalls(stub func(context.Context, *api.GetLatestProvidersRequest, ...grpc.CallOption) (api.Registry_GetLatestChannelEntriesThatProvideClient, error)) { + fake.getLatestChannelEntriesThatProvideMutex.Lock() + defer fake.getLatestChannelEntriesThatProvideMutex.Unlock() + fake.GetLatestChannelEntriesThatProvideStub = stub +} + +func (fake *FakeRegistryClient) GetLatestChannelEntriesThatProvideArgsForCall(i int) (context.Context, *api.GetLatestProvidersRequest, []grpc.CallOption) { + fake.getLatestChannelEntriesThatProvideMutex.RLock() + defer fake.getLatestChannelEntriesThatProvideMutex.RUnlock() + argsForCall := fake.getLatestChannelEntriesThatProvideArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3 +} + +func (fake *FakeRegistryClient) GetLatestChannelEntriesThatProvideReturns(result1 api.Registry_GetLatestChannelEntriesThatProvideClient, result2 error) { + fake.getLatestChannelEntriesThatProvideMutex.Lock() + defer fake.getLatestChannelEntriesThatProvideMutex.Unlock() + fake.GetLatestChannelEntriesThatProvideStub = nil + fake.getLatestChannelEntriesThatProvideReturns = struct { + result1 api.Registry_GetLatestChannelEntriesThatProvideClient + result2 error + }{result1, result2} +} + +func (fake *FakeRegistryClient) GetLatestChannelEntriesThatProvideReturnsOnCall(i int, result1 api.Registry_GetLatestChannelEntriesThatProvideClient, result2 error) { + fake.getLatestChannelEntriesThatProvideMutex.Lock() + defer fake.getLatestChannelEntriesThatProvideMutex.Unlock() + fake.GetLatestChannelEntriesThatProvideStub = nil + if fake.getLatestChannelEntriesThatProvideReturnsOnCall == nil { + fake.getLatestChannelEntriesThatProvideReturnsOnCall = make(map[int]struct { + result1 api.Registry_GetLatestChannelEntriesThatProvideClient + result2 error + }) + } + fake.getLatestChannelEntriesThatProvideReturnsOnCall[i] = struct { + result1 api.Registry_GetLatestChannelEntriesThatProvideClient + result2 error + }{result1, result2} +} + +func (fake *FakeRegistryClient) GetPackage(arg1 context.Context, arg2 *api.GetPackageRequest, arg3 ...grpc.CallOption) (*api.Package, error) { + fake.getPackageMutex.Lock() + ret, specificReturn := fake.getPackageReturnsOnCall[len(fake.getPackageArgsForCall)] + fake.getPackageArgsForCall = append(fake.getPackageArgsForCall, struct { + arg1 context.Context + arg2 *api.GetPackageRequest + arg3 []grpc.CallOption + }{arg1, arg2, arg3}) + fake.recordInvocation("GetPackage", []interface{}{arg1, arg2, arg3}) + fake.getPackageMutex.Unlock() + if fake.GetPackageStub != nil { + return fake.GetPackageStub(arg1, arg2, arg3...) + } + if specificReturn { + return ret.result1, ret.result2 + } + fakeReturns := fake.getPackageReturns + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *FakeRegistryClient) GetPackageCallCount() int { + fake.getPackageMutex.RLock() + defer fake.getPackageMutex.RUnlock() + return len(fake.getPackageArgsForCall) +} + +func (fake *FakeRegistryClient) GetPackageCalls(stub func(context.Context, *api.GetPackageRequest, ...grpc.CallOption) (*api.Package, error)) { + fake.getPackageMutex.Lock() + defer fake.getPackageMutex.Unlock() + fake.GetPackageStub = stub +} + +func (fake *FakeRegistryClient) GetPackageArgsForCall(i int) (context.Context, *api.GetPackageRequest, []grpc.CallOption) { + fake.getPackageMutex.RLock() + defer fake.getPackageMutex.RUnlock() + argsForCall := fake.getPackageArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3 +} + +func (fake *FakeRegistryClient) GetPackageReturns(result1 *api.Package, result2 error) { + fake.getPackageMutex.Lock() + defer fake.getPackageMutex.Unlock() + fake.GetPackageStub = nil + fake.getPackageReturns = struct { + result1 *api.Package + result2 error + }{result1, result2} +} + +func (fake *FakeRegistryClient) GetPackageReturnsOnCall(i int, result1 *api.Package, result2 error) { + fake.getPackageMutex.Lock() + defer fake.getPackageMutex.Unlock() + fake.GetPackageStub = nil + if fake.getPackageReturnsOnCall == nil { + fake.getPackageReturnsOnCall = make(map[int]struct { + result1 *api.Package + result2 error + }) + } + fake.getPackageReturnsOnCall[i] = struct { + result1 *api.Package + result2 error + }{result1, result2} +} + +func (fake *FakeRegistryClient) ListPackages(arg1 context.Context, arg2 *api.ListPackageRequest, arg3 ...grpc.CallOption) (api.Registry_ListPackagesClient, error) { + fake.listPackagesMutex.Lock() + ret, specificReturn := fake.listPackagesReturnsOnCall[len(fake.listPackagesArgsForCall)] + fake.listPackagesArgsForCall = append(fake.listPackagesArgsForCall, struct { + arg1 context.Context + arg2 *api.ListPackageRequest + arg3 []grpc.CallOption + }{arg1, arg2, arg3}) + fake.recordInvocation("ListPackages", []interface{}{arg1, arg2, arg3}) + fake.listPackagesMutex.Unlock() + if fake.ListPackagesStub != nil { + return fake.ListPackagesStub(arg1, arg2, arg3...) + } + if specificReturn { + return ret.result1, ret.result2 + } + fakeReturns := fake.listPackagesReturns + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *FakeRegistryClient) ListPackagesCallCount() int { + fake.listPackagesMutex.RLock() + defer fake.listPackagesMutex.RUnlock() + return len(fake.listPackagesArgsForCall) +} + +func (fake *FakeRegistryClient) ListPackagesCalls(stub func(context.Context, *api.ListPackageRequest, ...grpc.CallOption) (api.Registry_ListPackagesClient, error)) { + fake.listPackagesMutex.Lock() + defer fake.listPackagesMutex.Unlock() + fake.ListPackagesStub = stub +} + +func (fake *FakeRegistryClient) ListPackagesArgsForCall(i int) (context.Context, *api.ListPackageRequest, []grpc.CallOption) { + fake.listPackagesMutex.RLock() + defer fake.listPackagesMutex.RUnlock() + argsForCall := fake.listPackagesArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3 +} + +func (fake *FakeRegistryClient) ListPackagesReturns(result1 api.Registry_ListPackagesClient, result2 error) { + fake.listPackagesMutex.Lock() + defer fake.listPackagesMutex.Unlock() + fake.ListPackagesStub = nil + fake.listPackagesReturns = struct { + result1 api.Registry_ListPackagesClient + result2 error + }{result1, result2} +} + +func (fake *FakeRegistryClient) ListPackagesReturnsOnCall(i int, result1 api.Registry_ListPackagesClient, result2 error) { + fake.listPackagesMutex.Lock() + defer fake.listPackagesMutex.Unlock() + fake.ListPackagesStub = nil + if fake.listPackagesReturnsOnCall == nil { + fake.listPackagesReturnsOnCall = make(map[int]struct { + result1 api.Registry_ListPackagesClient + result2 error + }) + } + fake.listPackagesReturnsOnCall[i] = struct { + result1 api.Registry_ListPackagesClient + result2 error + }{result1, result2} +} + +func (fake *FakeRegistryClient) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.getBundleMutex.RLock() + defer fake.getBundleMutex.RUnlock() + fake.getBundleForChannelMutex.RLock() + defer fake.getBundleForChannelMutex.RUnlock() + fake.getBundleThatReplacesMutex.RLock() + defer fake.getBundleThatReplacesMutex.RUnlock() + fake.getChannelEntriesThatProvideMutex.RLock() + defer fake.getChannelEntriesThatProvideMutex.RUnlock() + fake.getChannelEntriesThatReplaceMutex.RLock() + defer fake.getChannelEntriesThatReplaceMutex.RUnlock() + fake.getDefaultBundleThatProvidesMutex.RLock() + defer fake.getDefaultBundleThatProvidesMutex.RUnlock() + fake.getLatestChannelEntriesThatProvideMutex.RLock() + defer fake.getLatestChannelEntriesThatProvideMutex.RUnlock() + fake.getPackageMutex.RLock() + defer fake.getPackageMutex.RUnlock() + fake.listPackagesMutex.RLock() + defer fake.listPackagesMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *FakeRegistryClient) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} + +var _ api.RegistryClient = new(FakeRegistryClient) diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/packagemanifest/interface.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/apps/interface.go similarity index 91% rename from vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/packagemanifest/interface.go rename to vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/apps/interface.go index 7215af7407..cbaa433d2d 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/packagemanifest/interface.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/apps/interface.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -16,11 +16,11 @@ limitations under the License. // Code generated by informer-gen. DO NOT EDIT. -package packagemanifest +package apps import ( + v1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/apps/v1alpha1" internalinterfaces "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/internalinterfaces" - v1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/packagemanifest/v1alpha1" ) // Interface provides access to each of this group's versions. diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/packagemanifest/v1alpha1/interface.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/apps/v1alpha1/interface.go similarity index 97% rename from vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/packagemanifest/v1alpha1/interface.go rename to vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/apps/v1alpha1/interface.go index 9a93e462bf..42ad4e3fe7 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/packagemanifest/v1alpha1/interface.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/apps/v1alpha1/interface.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/packagemanifest/v1alpha1/packagemanifest.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/apps/v1alpha1/packagemanifest.go similarity index 86% rename from vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/packagemanifest/v1alpha1/packagemanifest.go rename to vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/apps/v1alpha1/packagemanifest.go index 86b05f0b74..231ac91c21 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/packagemanifest/v1alpha1/packagemanifest.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/apps/v1alpha1/packagemanifest.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -21,10 +21,10 @@ package v1alpha1 import ( time "time" - packagemanifest_v1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1" + appsv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1" versioned "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned" internalinterfaces "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/internalinterfaces" - v1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/listers/packagemanifest/v1alpha1" + v1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/listers/apps/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" watch "k8s.io/apimachinery/pkg/watch" @@ -61,16 +61,16 @@ func NewFilteredPackageManifestInformer(client versioned.Interface, namespace st if tweakListOptions != nil { tweakListOptions(&options) } - return client.PackagemanifestV1alpha1().PackageManifests(namespace).List(options) + return client.AppsV1alpha1().PackageManifests(namespace).List(options) }, WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { tweakListOptions(&options) } - return client.PackagemanifestV1alpha1().PackageManifests(namespace).Watch(options) + return client.AppsV1alpha1().PackageManifests(namespace).Watch(options) }, }, - &packagemanifest_v1alpha1.PackageManifest{}, + &appsv1alpha1.PackageManifest{}, resyncPeriod, indexers, ) @@ -81,7 +81,7 @@ func (f *packageManifestInformer) defaultInformer(client versioned.Interface, re } func (f *packageManifestInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&packagemanifest_v1alpha1.PackageManifest{}, f.defaultInformer) + return f.factory.InformerFor(&appsv1alpha1.PackageManifest{}, f.defaultInformer) } func (f *packageManifestInformer) Lister() v1alpha1.PackageManifestLister { diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/factory.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/factory.go index dedf3fd990..c7de543ae2 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/factory.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/factory.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -24,8 +24,9 @@ import ( time "time" versioned "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned" + apps "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/apps" internalinterfaces "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/internalinterfaces" - packagemanifest "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/packagemanifest" + operators "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/operators" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" @@ -172,9 +173,14 @@ type SharedInformerFactory interface { ForResource(resource schema.GroupVersionResource) (GenericInformer, error) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool - Packagemanifest() packagemanifest.Interface + Apps() apps.Interface + Operators() operators.Interface } -func (f *sharedInformerFactory) Packagemanifest() packagemanifest.Interface { - return packagemanifest.New(f, f.namespace, f.tweakListOptions) +func (f *sharedInformerFactory) Apps() apps.Interface { + return apps.New(f, f.namespace, f.tweakListOptions) +} + +func (f *sharedInformerFactory) Operators() operators.Interface { + return operators.New(f, f.namespace, f.tweakListOptions) } diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/generic.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/generic.go index 20e4b63713..6b0943ded9 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/generic.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/generic.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -21,7 +21,8 @@ package externalversions import ( "fmt" - v1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1" + v1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1" + v1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1" schema "k8s.io/apimachinery/pkg/runtime/schema" cache "k8s.io/client-go/tools/cache" ) @@ -52,9 +53,13 @@ func (f *genericInformer) Lister() cache.GenericLister { // TODO extend this to unknown resources with a client pool func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) { switch resource { - // Group=packagemanifest, Version=v1alpha1 + // Group=apps.redhat.com, Version=v1alpha1 case v1alpha1.SchemeGroupVersion.WithResource("packagemanifests"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Packagemanifest().V1alpha1().PackageManifests().Informer()}, nil + return &genericInformer{resource: resource.GroupResource(), informer: f.Apps().V1alpha1().PackageManifests().Informer()}, nil + + // Group=operators.coreos.com, Version=v1 + case v1.SchemeGroupVersion.WithResource("packagemanifests"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Operators().V1().PackageManifests().Informer()}, nil } diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/internalinterfaces/factory_interfaces.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/internalinterfaces/factory_interfaces.go index 16b17cc781..f875805a63 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/internalinterfaces/factory_interfaces.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/internalinterfaces/factory_interfaces.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/operators/interface.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/operators/interface.go new file mode 100644 index 0000000000..3ab21521c3 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/operators/interface.go @@ -0,0 +1,46 @@ +/* +Copyright 2019 Red Hat, 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 informer-gen. DO NOT EDIT. + +package operators + +import ( + internalinterfaces "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/internalinterfaces" + v1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/operators/v1" +) + +// Interface provides access to each of this group's versions. +type Interface interface { + // V1 provides access to shared informers for resources in V1. + V1() v1.Interface +} + +type group struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// V1 returns a new v1.Interface. +func (g *group) V1() v1.Interface { + return v1.New(g.factory, g.namespace, g.tweakListOptions) +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/operators/v1/interface.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/operators/v1/interface.go new file mode 100644 index 0000000000..d5126f9bb2 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/operators/v1/interface.go @@ -0,0 +1,45 @@ +/* +Copyright 2019 Red Hat, 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 informer-gen. DO NOT EDIT. + +package v1 + +import ( + internalinterfaces "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // PackageManifests returns a PackageManifestInformer. + PackageManifests() PackageManifestInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// PackageManifests returns a PackageManifestInformer. +func (v *version) PackageManifests() PackageManifestInformer { + return &packageManifestInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/operators/v1/packagemanifest.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/operators/v1/packagemanifest.go new file mode 100644 index 0000000000..e50caf95c0 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/operators/v1/packagemanifest.go @@ -0,0 +1,89 @@ +/* +Copyright 2019 Red Hat, 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 informer-gen. DO NOT EDIT. + +package v1 + +import ( + time "time" + + operatorsv1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1" + versioned "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned" + internalinterfaces "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/externalversions/internalinterfaces" + v1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/listers/operators/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" +) + +// PackageManifestInformer provides access to a shared informer and lister for +// PackageManifests. +type PackageManifestInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.PackageManifestLister +} + +type packageManifestInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewPackageManifestInformer constructs a new informer for PackageManifest type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewPackageManifestInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredPackageManifestInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredPackageManifestInformer constructs a new informer for PackageManifest type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredPackageManifestInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.OperatorsV1().PackageManifests(namespace).List(options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.OperatorsV1().PackageManifests(namespace).Watch(options) + }, + }, + &operatorsv1.PackageManifest{}, + resyncPeriod, + indexers, + ) +} + +func (f *packageManifestInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredPackageManifestInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *packageManifestInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&operatorsv1.PackageManifest{}, f.defaultInformer) +} + +func (f *packageManifestInformer) Lister() v1.PackageManifestLister { + return v1.NewPackageManifestLister(f.Informer().GetIndexer()) +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/internalversion/factory.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/internalversion/factory.go new file mode 100644 index 0000000000..8b5dc2dd14 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/internalversion/factory.go @@ -0,0 +1,180 @@ +/* +Copyright 2019 Red Hat, 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 informer-gen. DO NOT EDIT. + +package internalversion + +import ( + reflect "reflect" + sync "sync" + time "time" + + internalversion "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion" + internalinterfaces "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/internalversion/internalinterfaces" + operators "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/internalversion/operators" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" + cache "k8s.io/client-go/tools/cache" +) + +// SharedInformerOption defines the functional option type for SharedInformerFactory. +type SharedInformerOption func(*sharedInformerFactory) *sharedInformerFactory + +type sharedInformerFactory struct { + client internalversion.Interface + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc + lock sync.Mutex + defaultResync time.Duration + customResync map[reflect.Type]time.Duration + + informers map[reflect.Type]cache.SharedIndexInformer + // startedInformers is used for tracking which informers have been started. + // This allows Start() to be called multiple times safely. + startedInformers map[reflect.Type]bool +} + +// WithCustomResyncConfig sets a custom resync period for the specified informer types. +func WithCustomResyncConfig(resyncConfig map[v1.Object]time.Duration) SharedInformerOption { + return func(factory *sharedInformerFactory) *sharedInformerFactory { + for k, v := range resyncConfig { + factory.customResync[reflect.TypeOf(k)] = v + } + return factory + } +} + +// WithTweakListOptions sets a custom filter on all listers of the configured SharedInformerFactory. +func WithTweakListOptions(tweakListOptions internalinterfaces.TweakListOptionsFunc) SharedInformerOption { + return func(factory *sharedInformerFactory) *sharedInformerFactory { + factory.tweakListOptions = tweakListOptions + return factory + } +} + +// WithNamespace limits the SharedInformerFactory to the specified namespace. +func WithNamespace(namespace string) SharedInformerOption { + return func(factory *sharedInformerFactory) *sharedInformerFactory { + factory.namespace = namespace + return factory + } +} + +// NewSharedInformerFactory constructs a new instance of sharedInformerFactory for all namespaces. +func NewSharedInformerFactory(client internalversion.Interface, defaultResync time.Duration) SharedInformerFactory { + return NewSharedInformerFactoryWithOptions(client, defaultResync) +} + +// NewFilteredSharedInformerFactory constructs a new instance of sharedInformerFactory. +// Listers obtained via this SharedInformerFactory will be subject to the same filters +// as specified here. +// Deprecated: Please use NewSharedInformerFactoryWithOptions instead +func NewFilteredSharedInformerFactory(client internalversion.Interface, defaultResync time.Duration, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) SharedInformerFactory { + return NewSharedInformerFactoryWithOptions(client, defaultResync, WithNamespace(namespace), WithTweakListOptions(tweakListOptions)) +} + +// NewSharedInformerFactoryWithOptions constructs a new instance of a SharedInformerFactory with additional options. +func NewSharedInformerFactoryWithOptions(client internalversion.Interface, defaultResync time.Duration, options ...SharedInformerOption) SharedInformerFactory { + factory := &sharedInformerFactory{ + client: client, + namespace: v1.NamespaceAll, + defaultResync: defaultResync, + informers: make(map[reflect.Type]cache.SharedIndexInformer), + startedInformers: make(map[reflect.Type]bool), + customResync: make(map[reflect.Type]time.Duration), + } + + // Apply all options + for _, opt := range options { + factory = opt(factory) + } + + return factory +} + +// Start initializes all requested informers. +func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) { + f.lock.Lock() + defer f.lock.Unlock() + + for informerType, informer := range f.informers { + if !f.startedInformers[informerType] { + go informer.Run(stopCh) + f.startedInformers[informerType] = true + } + } +} + +// WaitForCacheSync waits for all started informers' cache were synced. +func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool { + informers := func() map[reflect.Type]cache.SharedIndexInformer { + f.lock.Lock() + defer f.lock.Unlock() + + informers := map[reflect.Type]cache.SharedIndexInformer{} + for informerType, informer := range f.informers { + if f.startedInformers[informerType] { + informers[informerType] = informer + } + } + return informers + }() + + res := map[reflect.Type]bool{} + for informType, informer := range informers { + res[informType] = cache.WaitForCacheSync(stopCh, informer.HasSynced) + } + return res +} + +// InternalInformerFor returns the SharedIndexInformer for obj using an internal +// client. +func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer { + f.lock.Lock() + defer f.lock.Unlock() + + informerType := reflect.TypeOf(obj) + informer, exists := f.informers[informerType] + if exists { + return informer + } + + resyncPeriod, exists := f.customResync[informerType] + if !exists { + resyncPeriod = f.defaultResync + } + + informer = newFunc(f.client, resyncPeriod) + f.informers[informerType] = informer + + return informer +} + +// SharedInformerFactory provides shared informers for resources in all known +// API group versions. +type SharedInformerFactory interface { + internalinterfaces.SharedInformerFactory + ForResource(resource schema.GroupVersionResource) (GenericInformer, error) + WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool + + Operators() operators.Interface +} + +func (f *sharedInformerFactory) Operators() operators.Interface { + return operators.New(f, f.namespace, f.tweakListOptions) +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/internalversion/generic.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/internalversion/generic.go new file mode 100644 index 0000000000..7954664959 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/internalversion/generic.go @@ -0,0 +1,62 @@ +/* +Copyright 2019 Red Hat, 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 informer-gen. DO NOT EDIT. + +package internalversion + +import ( + "fmt" + + operators "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators" + schema "k8s.io/apimachinery/pkg/runtime/schema" + cache "k8s.io/client-go/tools/cache" +) + +// GenericInformer is type of SharedIndexInformer which will locate and delegate to other +// sharedInformers based on type +type GenericInformer interface { + Informer() cache.SharedIndexInformer + Lister() cache.GenericLister +} + +type genericInformer struct { + informer cache.SharedIndexInformer + resource schema.GroupResource +} + +// Informer returns the SharedIndexInformer. +func (f *genericInformer) Informer() cache.SharedIndexInformer { + return f.informer +} + +// Lister returns the GenericLister. +func (f *genericInformer) Lister() cache.GenericLister { + return cache.NewGenericLister(f.Informer().GetIndexer(), f.resource) +} + +// ForResource gives generic access to a shared informer of the matching type +// TODO extend this to unknown resources with a client pool +func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) { + switch resource { + // Group=operators.coreos.com, Version=internalVersion + case operators.SchemeGroupVersion.WithResource("packagemanifests"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Operators().InternalVersion().PackageManifests().Informer()}, nil + + } + + return nil, fmt.Errorf("no informer found for %v", resource) +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/internalversion/internalinterfaces/factory_interfaces.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/internalversion/internalinterfaces/factory_interfaces.go new file mode 100644 index 0000000000..228f80bd94 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/internalversion/internalinterfaces/factory_interfaces.go @@ -0,0 +1,38 @@ +/* +Copyright 2019 Red Hat, 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 informer-gen. DO NOT EDIT. + +package internalinterfaces + +import ( + time "time" + + internalversion "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + cache "k8s.io/client-go/tools/cache" +) + +type NewInformerFunc func(internalversion.Interface, time.Duration) cache.SharedIndexInformer + +// SharedInformerFactory a small interface to allow for adding an informer without an import cycle +type SharedInformerFactory interface { + Start(stopCh <-chan struct{}) + InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer +} + +type TweakListOptionsFunc func(*v1.ListOptions) diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/internalversion/operators/interface.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/internalversion/operators/interface.go new file mode 100644 index 0000000000..94246fc898 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/internalversion/operators/interface.go @@ -0,0 +1,46 @@ +/* +Copyright 2019 Red Hat, 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 informer-gen. DO NOT EDIT. + +package operators + +import ( + internalinterfaces "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/internalversion/internalinterfaces" + internalversion "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/internalversion/operators/internalversion" +) + +// Interface provides access to each of this group's versions. +type Interface interface { + // InternalVersion provides access to shared informers for resources in InternalVersion. + InternalVersion() internalversion.Interface +} + +type group struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// InternalVersion returns a new internalversion.Interface. +func (g *group) InternalVersion() internalversion.Interface { + return internalversion.New(g.factory, g.namespace, g.tweakListOptions) +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/internalversion/operators/internalversion/interface.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/internalversion/operators/internalversion/interface.go new file mode 100644 index 0000000000..bb9a44f668 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/internalversion/operators/internalversion/interface.go @@ -0,0 +1,45 @@ +/* +Copyright 2019 Red Hat, 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 informer-gen. DO NOT EDIT. + +package internalversion + +import ( + internalinterfaces "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/internalversion/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // PackageManifests returns a PackageManifestInformer. + PackageManifests() PackageManifestInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// PackageManifests returns a PackageManifestInformer. +func (v *version) PackageManifests() PackageManifestInformer { + return &packageManifestInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/internalversion/operators/internalversion/packagemanifest.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/internalversion/operators/internalversion/packagemanifest.go new file mode 100644 index 0000000000..a507bc1176 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/internalversion/operators/internalversion/packagemanifest.go @@ -0,0 +1,89 @@ +/* +Copyright 2019 Red Hat, 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 informer-gen. DO NOT EDIT. + +package internalversion + +import ( + time "time" + + operators "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators" + clientsetinternalversion "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/internalversion" + internalinterfaces "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/informers/internalversion/internalinterfaces" + internalversion "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/listers/operators/internalversion" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" +) + +// PackageManifestInformer provides access to a shared informer and lister for +// PackageManifests. +type PackageManifestInformer interface { + Informer() cache.SharedIndexInformer + Lister() internalversion.PackageManifestLister +} + +type packageManifestInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewPackageManifestInformer constructs a new informer for PackageManifest type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewPackageManifestInformer(client clientsetinternalversion.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredPackageManifestInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredPackageManifestInformer constructs a new informer for PackageManifest type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredPackageManifestInformer(client clientsetinternalversion.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.Operators().PackageManifests(namespace).List(options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.Operators().PackageManifests(namespace).Watch(options) + }, + }, + &operators.PackageManifest{}, + resyncPeriod, + indexers, + ) +} + +func (f *packageManifestInformer) defaultInformer(client clientsetinternalversion.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredPackageManifestInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *packageManifestInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&operators.PackageManifest{}, f.defaultInformer) +} + +func (f *packageManifestInformer) Lister() internalversion.PackageManifestLister { + return internalversion.NewPackageManifestLister(f.Informer().GetIndexer()) +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/listers/packagemanifest/v1alpha1/expansion_generated.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/listers/apps/v1alpha1/expansion_generated.go similarity index 96% rename from vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/listers/packagemanifest/v1alpha1/expansion_generated.go rename to vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/listers/apps/v1alpha1/expansion_generated.go index c6cd3e85ea..cac91be624 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/listers/packagemanifest/v1alpha1/expansion_generated.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/listers/apps/v1alpha1/expansion_generated.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/listers/packagemanifest/v1alpha1/packagemanifest.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/listers/apps/v1alpha1/packagemanifest.go similarity index 97% rename from vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/listers/packagemanifest/v1alpha1/packagemanifest.go rename to vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/listers/apps/v1alpha1/packagemanifest.go index 54222df064..4eb4e878ea 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/listers/packagemanifest/v1alpha1/packagemanifest.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/listers/apps/v1alpha1/packagemanifest.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2019 Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -19,7 +19,7 @@ limitations under the License. package v1alpha1 import ( - v1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1" + v1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/apps/v1alpha1" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" "k8s.io/client-go/tools/cache" diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/listers/operators/internalversion/expansion_generated.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/listers/operators/internalversion/expansion_generated.go new file mode 100644 index 0000000000..29efada050 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/listers/operators/internalversion/expansion_generated.go @@ -0,0 +1,27 @@ +/* +Copyright 2019 Red Hat, 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 lister-gen. DO NOT EDIT. + +package internalversion + +// PackageManifestListerExpansion allows custom methods to be added to +// PackageManifestLister. +type PackageManifestListerExpansion interface{} + +// PackageManifestNamespaceListerExpansion allows custom methods to be added to +// PackageManifestNamespaceLister. +type PackageManifestNamespaceListerExpansion interface{} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/listers/operators/internalversion/packagemanifest.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/listers/operators/internalversion/packagemanifest.go new file mode 100644 index 0000000000..7089a179c8 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/listers/operators/internalversion/packagemanifest.go @@ -0,0 +1,94 @@ +/* +Copyright 2019 Red Hat, 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 lister-gen. DO NOT EDIT. + +package internalversion + +import ( + operators "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// PackageManifestLister helps list PackageManifests. +type PackageManifestLister interface { + // List lists all PackageManifests in the indexer. + List(selector labels.Selector) (ret []*operators.PackageManifest, err error) + // PackageManifests returns an object that can list and get PackageManifests. + PackageManifests(namespace string) PackageManifestNamespaceLister + PackageManifestListerExpansion +} + +// packageManifestLister implements the PackageManifestLister interface. +type packageManifestLister struct { + indexer cache.Indexer +} + +// NewPackageManifestLister returns a new PackageManifestLister. +func NewPackageManifestLister(indexer cache.Indexer) PackageManifestLister { + return &packageManifestLister{indexer: indexer} +} + +// List lists all PackageManifests in the indexer. +func (s *packageManifestLister) List(selector labels.Selector) (ret []*operators.PackageManifest, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*operators.PackageManifest)) + }) + return ret, err +} + +// PackageManifests returns an object that can list and get PackageManifests. +func (s *packageManifestLister) PackageManifests(namespace string) PackageManifestNamespaceLister { + return packageManifestNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// PackageManifestNamespaceLister helps list and get PackageManifests. +type PackageManifestNamespaceLister interface { + // List lists all PackageManifests in the indexer for a given namespace. + List(selector labels.Selector) (ret []*operators.PackageManifest, err error) + // Get retrieves the PackageManifest from the indexer for a given namespace and name. + Get(name string) (*operators.PackageManifest, error) + PackageManifestNamespaceListerExpansion +} + +// packageManifestNamespaceLister implements the PackageManifestNamespaceLister +// interface. +type packageManifestNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all PackageManifests in the indexer for a given namespace. +func (s packageManifestNamespaceLister) List(selector labels.Selector) (ret []*operators.PackageManifest, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*operators.PackageManifest)) + }) + return ret, err +} + +// Get retrieves the PackageManifest from the indexer for a given namespace and name. +func (s packageManifestNamespaceLister) Get(name string) (*operators.PackageManifest, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(operators.Resource("packagemanifest"), name) + } + return obj.(*operators.PackageManifest), nil +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/listers/operators/v1/expansion_generated.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/listers/operators/v1/expansion_generated.go new file mode 100644 index 0000000000..95596f6f09 --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/listers/operators/v1/expansion_generated.go @@ -0,0 +1,27 @@ +/* +Copyright 2019 Red Hat, 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 lister-gen. DO NOT EDIT. + +package v1 + +// PackageManifestListerExpansion allows custom methods to be added to +// PackageManifestLister. +type PackageManifestListerExpansion interface{} + +// PackageManifestNamespaceListerExpansion allows custom methods to be added to +// PackageManifestNamespaceLister. +type PackageManifestNamespaceListerExpansion interface{} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/listers/operators/v1/packagemanifest.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/listers/operators/v1/packagemanifest.go new file mode 100644 index 0000000000..5e82f6075e --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/listers/operators/v1/packagemanifest.go @@ -0,0 +1,94 @@ +/* +Copyright 2019 Red Hat, 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 lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// PackageManifestLister helps list PackageManifests. +type PackageManifestLister interface { + // List lists all PackageManifests in the indexer. + List(selector labels.Selector) (ret []*v1.PackageManifest, err error) + // PackageManifests returns an object that can list and get PackageManifests. + PackageManifests(namespace string) PackageManifestNamespaceLister + PackageManifestListerExpansion +} + +// packageManifestLister implements the PackageManifestLister interface. +type packageManifestLister struct { + indexer cache.Indexer +} + +// NewPackageManifestLister returns a new PackageManifestLister. +func NewPackageManifestLister(indexer cache.Indexer) PackageManifestLister { + return &packageManifestLister{indexer: indexer} +} + +// List lists all PackageManifests in the indexer. +func (s *packageManifestLister) List(selector labels.Selector) (ret []*v1.PackageManifest, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.PackageManifest)) + }) + return ret, err +} + +// PackageManifests returns an object that can list and get PackageManifests. +func (s *packageManifestLister) PackageManifests(namespace string) PackageManifestNamespaceLister { + return packageManifestNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// PackageManifestNamespaceLister helps list and get PackageManifests. +type PackageManifestNamespaceLister interface { + // List lists all PackageManifests in the indexer for a given namespace. + List(selector labels.Selector) (ret []*v1.PackageManifest, err error) + // Get retrieves the PackageManifest from the indexer for a given namespace and name. + Get(name string) (*v1.PackageManifest, error) + PackageManifestNamespaceListerExpansion +} + +// packageManifestNamespaceLister implements the PackageManifestNamespaceLister +// interface. +type packageManifestNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all PackageManifests in the indexer for a given namespace. +func (s packageManifestNamespaceLister) List(selector labels.Selector) (ret []*v1.PackageManifest, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.PackageManifest)) + }) + return ret, err +} + +// Get retrieves the PackageManifest from the indexer for a given namespace and name. +func (s packageManifestNamespaceLister) Get(name string) (*v1.PackageManifest, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("packagemanifest"), name) + } + return obj.(*v1.PackageManifest), nil +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/provider/inmem.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/provider/inmem.go deleted file mode 100644 index 6156f5778e..0000000000 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/provider/inmem.go +++ /dev/null @@ -1,263 +0,0 @@ -package provider - -import ( - "encoding/json" - "fmt" - "sync" - "time" - - "github.com/ghodss/yaml" - log "github.com/sirupsen/logrus" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/tools/cache" - "k8s.io/client-go/util/workqueue" - - operatorsv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" - "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/queueinformer" - packagev1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1" -) - -const ( - // ConfigMapPackageName is the key for package ConfigMap data - ConfigMapPackageName = "packages" - - // ConfigMapCSVName is the key for CSV ConfigMap data - ConfigMapCSVName = "clusterServiceVersions" -) - -type packageKey struct { - catalogSourceName string - catalogSourceNamespace string - packageName string -} - -// InMemoryProvider syncs and provides PackageManifests from the cluster in an in-memory cache -type InMemoryProvider struct { - *queueinformer.Operator - - mu sync.RWMutex - manifests map[packageKey]packagev1alpha1.PackageManifest -} - -// NewInMemoryProvider returns a pointer to a new InMemoryProvider instance -func NewInMemoryProvider(informers []cache.SharedIndexInformer, queueOperator *queueinformer.Operator) *InMemoryProvider { - // instantiate the in-mem provider - prov := &InMemoryProvider{ - Operator: queueOperator, - manifests: make(map[packageKey]packagev1alpha1.PackageManifest), - } - - // register CatalogSource informers. - queue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "catalogsources") - queueInformers := queueinformer.New( - queue, - informers, - prov.syncCatalogSource, - nil, - "catsrc", - ) - for _, informer := range queueInformers { - prov.RegisterQueueInformer(informer) - } - - return prov -} - -// parsePackageManifestsFromConfigMap returns a list of PackageManifests from a given ConfigMap -func parsePackageManifestsFromConfigMap(cm *corev1.ConfigMap, catalogSourceName, catalogSourceNamespace string) ([]packagev1alpha1.PackageManifest, error) { - cmName := cm.GetName() - logger := log.WithFields(log.Fields{ - "Action": "Load ConfigMap", - "name": cmName, - }) - - found := false - csvs := make(map[string]operatorsv1alpha1.ClusterServiceVersion) - csvListYaml, ok := cm.Data[ConfigMapCSVName] - if ok { - logger.Debug("ConfigMap contains CSVsf") - csvListJSON, err := yaml.YAMLToJSON([]byte(csvListYaml)) - if err != nil { - log.Debugf("Load ConfigMap -- ERROR %s : error=%s", cmName, err) - return nil, fmt.Errorf("error loading CSV list yaml from ConfigMap %s: %s", cmName, err) - } - - var parsedCSVList []operatorsv1alpha1.ClusterServiceVersion - err = json.Unmarshal([]byte(csvListJSON), &parsedCSVList) - if err != nil { - log.Debugf("Load ConfigMap -- ERROR %s : error=%s", cmName, err) - return nil, fmt.Errorf("error parsing CSV list (json) from ConfigMap %s: %s", cmName, err) - } - - for _, csv := range parsedCSVList { - found = true - - // TODO: add check for invalid CSV definitions - log.Debugf("found csv %s", csv.GetName()) - csvs[csv.GetName()] = csv - } - } - - manifests := []packagev1alpha1.PackageManifest{} - packageListYaml, ok := cm.Data[ConfigMapPackageName] - if ok { - logger.Debug("ConfigMap contains packages") - packageListJSON, err := yaml.YAMLToJSON([]byte(packageListYaml)) - if err != nil { - logger.Debugf("ERROR: %s", err) - return nil, fmt.Errorf("error loading package list yaml from ConfigMap %s: %s", cmName, err) - } - - var parsedStatuses []packagev1alpha1.PackageManifestStatus - err = json.Unmarshal([]byte(packageListJSON), &parsedStatuses) - if err != nil { - logger.Debugf("ERROR: %s", err) - return nil, fmt.Errorf("error parsing package list (json) from ConfigMap %s: %s", cmName, err) - } - - for _, status := range parsedStatuses { - found = true - - // add the name and namespace of the CatalogSource - manifest := packagev1alpha1.PackageManifest{ - ObjectMeta: metav1.ObjectMeta{ - Name: status.PackageName, - Namespace: cm.GetNamespace(), - Labels: map[string]string{}, - }, - Status: status, - } - - manifest.Status.CatalogSourceName = catalogSourceName - manifest.Status.CatalogSourceNamespace = catalogSourceNamespace - - // add all PackageChannel CSVDescriptions - for i, channel := range manifest.Status.Channels { - csv, ok := csvs[channel.CurrentCSVName] - if !ok { - return nil, fmt.Errorf("packagemanifest %s references non-existent csv %s", manifest.Status.PackageName, channel.CurrentCSVName) - } - - manifest.Status.Channels[i].CurrentCSVDesc = packagev1alpha1.CreateCSVDescription(&csv) - - // set the Provider - if manifest.Status.DefaultChannelName != "" && csv.GetName() == manifest.Status.DefaultChannelName || i == 0 { - manifest.Status.Provider = packagev1alpha1.AppLink{ - Name: csv.Spec.Provider.Name, - URL: csv.Spec.Provider.URL, - } - - // add Provider as a label - manifest.ObjectMeta.Labels["provider"] = manifest.Status.Provider.Name - manifest.ObjectMeta.Labels["provider-url"] = manifest.Status.Provider.URL - } - } - - // set CatalogSource labels - manifest.ObjectMeta.Labels["catalog"] = manifest.Status.CatalogSourceName - manifest.ObjectMeta.Labels["catalog-namespace"] = manifest.Status.CatalogSourceNamespace - - log.Debugf("retrieved packagemanifest %s", manifest.GetName()) - manifests = append(manifests, manifest) - } - } - - if !found { - logger.Debug("ERROR: No valid resource found") - return nil, fmt.Errorf("error parsing ConfigMap %s: no valid resources found", cmName) - } - - return manifests, nil -} - -func (m *InMemoryProvider) syncCatalogSource(obj interface{}) error { - // assert as CatalogSource - catsrc, ok := obj.(*operatorsv1alpha1.CatalogSource) - if !ok { - log.Debugf("wrong type: %#v", obj) - return fmt.Errorf("casting catalog source failed") - } - - var manifests []packagev1alpha1.PackageManifest - - // handle by sourceType - switch catsrc.Spec.SourceType { - case "internal": - // get the CatalogSource's ConfigMap - cm, err := m.OpClient.KubernetesInterface().CoreV1().ConfigMaps(catsrc.GetNamespace()).Get(catsrc.Spec.ConfigMap, metav1.GetOptions{}) - if err != nil { - return fmt.Errorf("failed to get catalog config map %s when updating status: %s", catsrc.Spec.ConfigMap, err) - } - - // parse PackageManifest from ConfigMap - manifests, err = parsePackageManifestsFromConfigMap(cm, catsrc.GetName(), catsrc.GetNamespace()) - if err != nil { - return fmt.Errorf("failed to load package manifest from config map %s", cm.GetName()) - } - - default: - return fmt.Errorf("catalog source %s in namespace %s source type %s not recognized", catsrc.GetName(), catsrc.GetNamespace(), catsrc.Spec.SourceType) - } - - // update manifests - m.mu.Lock() - defer m.mu.Unlock() - for _, manifest := range manifests { - key := packageKey{ - catalogSourceName: manifest.Status.CatalogSourceName, - catalogSourceNamespace: manifest.Status.CatalogSourceNamespace, - packageName: manifest.GetName(), - } - - if pm, ok := m.manifests[key]; ok { - // use existing CreationTimestamp - manifest.CreationTimestamp = pm.ObjectMeta.CreationTimestamp - } else { - // set CreationTimestamp if first time seeing the PackageManifest - manifest.CreationTimestamp = metav1.NewTime(time.Now()) - } - - log.Debugf("storing packagemanifest at %+v", key) - m.manifests[key] = manifest - } - - return nil -} - -// ListPackageManifests implements PackageManifestProvider.ListPackageManifests() -func (m *InMemoryProvider) ListPackageManifests(namespace string) (*packagev1alpha1.PackageManifestList, error) { - manifestList := &packagev1alpha1.PackageManifestList{} - - m.mu.RLock() - defer m.mu.RUnlock() - - if len(m.manifests) > 0 { - var matching []packagev1alpha1.PackageManifest - for _, manifest := range m.manifests { - if manifest.GetNamespace() == namespace { - // tack on the csv spec for each channel - matching = append(matching, manifest) - } - } - - manifestList.Items = matching - } - - return manifestList, nil -} - -// GetPackageManifest implements PackageManifestProvider.GetPackageManifest(...) -func (m *InMemoryProvider) GetPackageManifest(namespace, name string) (*packagev1alpha1.PackageManifest, error) { - m.mu.RLock() - defer m.mu.RUnlock() - - var manifest packagev1alpha1.PackageManifest - for key, pm := range m.manifests { - if key.packageName == name && key.catalogSourceNamespace == namespace { - manifest = pm - } - } - - return &manifest, nil -} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/provider/interfaces.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/provider/interfaces.go index 3a107b0147..980ac4031b 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/provider/interfaces.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/provider/interfaces.go @@ -1,10 +1,8 @@ package provider -import ( - "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1" -) +import "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators" type PackageManifestProvider interface { - ListPackageManifests(namespace string) (*v1alpha1.PackageManifestList, error) - GetPackageManifest(namespace, name string) (*v1alpha1.PackageManifest, error) + Get(name, namespace string) (*operators.PackageManifest, error) + List(namespace string) (*operators.PackageManifestList, error) } diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/provider/registry.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/provider/registry.go new file mode 100644 index 0000000000..5e459c476a --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/provider/registry.go @@ -0,0 +1,339 @@ +package provider + +import ( + "context" + "encoding/json" + "fmt" + "io" + "sync" + "time" + + "github.com/operator-framework/operator-registry/pkg/api" + "github.com/sirupsen/logrus" + "google.golang.org/grpc" + "google.golang.org/grpc/connectivity" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/client-go/tools/cache" + "k8s.io/client-go/util/workqueue" + + operatorsv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned" + "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions" + "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/queueinformer" + "github.com/operator-framework/operator-lifecycle-manager/pkg/metrics" + "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators" +) + +const ( + defaultConnectionTimeout = 5 * time.Second +) + +type sourceKey struct { + name string + namespace string +} + +type registryClient struct { + api.RegistryClient + source *operatorsv1alpha1.CatalogSource + conn *grpc.ClientConn +} + +func newRegistryClient(source *operatorsv1alpha1.CatalogSource, conn *grpc.ClientConn) registryClient { + return registryClient{ + RegistryClient: api.NewRegistryClient(conn), + source: source, + conn: conn, + } +} + +// RegistryProvider aggregates several `CatalogSources` and establishes gRPC connections to their registry servers. +type RegistryProvider struct { + *queueinformer.Operator + + mu sync.RWMutex + globalNamespace string + clients map[sourceKey]registryClient +} + +var _ PackageManifestProvider = &RegistryProvider{} + +func NewRegistryProvider(crClient versioned.Interface, operator *queueinformer.Operator, wakeupInterval time.Duration, watchedNamespaces []string, globalNamespace string) *RegistryProvider { + p := &RegistryProvider{ + Operator: operator, + + globalNamespace: globalNamespace, + clients: make(map[sourceKey]registryClient), + } + + sourceHandlers := &cache.ResourceEventHandlerFuncs{ + DeleteFunc: p.catalogSourceDeleted, + } + for _, namespace := range watchedNamespaces { + factory := externalversions.NewSharedInformerFactoryWithOptions(crClient, wakeupInterval, externalversions.WithNamespace(namespace)) + sourceInformer := factory.Operators().V1alpha1().CatalogSources() + + // Register queue and QueueInformer + logrus.WithField("namespace", namespace).Info("watching catalogsources") + queueName := fmt.Sprintf("%s/catalogsources", namespace) + sourceQueue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), queueName) + sourceQueueInformer := queueinformer.NewInformer(sourceQueue, sourceInformer.Informer(), p.syncCatalogSource, sourceHandlers, queueName, metrics.NewMetricsNil(), logrus.New()) + p.RegisterQueueInformer(sourceQueueInformer) + } + + return p +} + +func (p *RegistryProvider) getClient(key sourceKey) (registryClient, bool) { + p.mu.RLock() + defer p.mu.RUnlock() + + client, ok := p.clients[key] + return client, ok +} + +func (p *RegistryProvider) setClient(client registryClient, key sourceKey) { + p.mu.Lock() + defer p.mu.Unlock() + + p.clients[key] = client +} + +func (p *RegistryProvider) removeClient(key sourceKey) (registryClient, bool) { + p.mu.Lock() + defer p.mu.Unlock() + + client, ok := p.clients[key] + if !ok { + return registryClient{}, false + } + + delete(p.clients, key) + return client, true +} + +func (p *RegistryProvider) syncCatalogSource(obj interface{}) (syncError error) { + source, ok := obj.(*operatorsv1alpha1.CatalogSource) + if !ok { + logrus.Errorf("catalogsource type assertion failed: wrong type: %#v", obj) + } + + logger := logrus.WithFields(logrus.Fields{ + "action": "sync catalogsource", + "name": source.GetName(), + "namespace": source.GetNamespace(), + }) + + if source.Status.RegistryServiceStatus == nil { + logger.Debug("registry service is not ready for grpc connection") + return + } + + key := sourceKey{source.GetName(), source.GetNamespace()} + client, ok := p.getClient(key) + if ok && source.Status.RegistryServiceStatus.ServiceName != "" { + logger.Info("update detected, attempting to reset grpc connection") + client.conn.ResetConnectBackoff() + + ctx, cancel := context.WithTimeout(context.TODO(), defaultConnectionTimeout) + defer cancel() + + changed := client.conn.WaitForStateChange(ctx, connectivity.TransientFailure) + if !changed { + logger.Debugf("grpc connection reset timeout") + syncError = fmt.Errorf("grpc connection reset timeout") + return + } + + logger.Info("grpc connection reset") + return + } else if ok { + // Address type grpc CatalogSource, drop the connection dial in to the new address + client.conn.Close() + } + + logger.Info("attempting to add a new grpc connection") + conn, err := grpc.Dial(source.Address(), grpc.WithInsecure()) + if err != nil { + logger.WithField("err", err.Error()).Errorf("could not connect to registry service") + syncError = err + return + } + + p.setClient(newRegistryClient(source, conn), key) + logger.Info("new grpc connection added") + + return +} + +func (p *RegistryProvider) catalogSourceDeleted(obj interface{}) { + catsrc, ok := obj.(metav1.Object) + if !ok { + if !ok { + tombstone, ok := obj.(cache.DeletedFinalStateUnknown) + if !ok { + utilruntime.HandleError(fmt.Errorf("couldn't get object from tombstone %#v", obj)) + return + } + + catsrc, ok = tombstone.Obj.(metav1.Object) + if !ok { + utilruntime.HandleError(fmt.Errorf("tombstone contained object that is not a Namespace %#v", obj)) + return + } + } + } + + logger := logrus.WithFields(logrus.Fields{ + "action": "CatalogSource Deleted", + "name": catsrc.GetName(), + "namespace": catsrc.GetNamespace(), + }) + logger.Debugf("attempting to remove grpc connection") + + key := sourceKey{catsrc.GetName(), catsrc.GetNamespace()} + client, removed := p.removeClient(key) + if removed { + err := client.conn.Close() + if err != nil { + logger.WithField("err", err.Error()).Error("error closing connection") + utilruntime.HandleError(fmt.Errorf("error closing connection %s", err.Error())) + return + } + logger.Debug("grpc connection removed") + return + } + + logger.Debugf("no gRPC connection to remove") + +} + +func (p *RegistryProvider) Get(namespace, name string) (*operators.PackageManifest, error) { + logger := logrus.WithFields(logrus.Fields{ + "action": "Get PackageManifest", + "name": name, + "namespace": namespace, + }) + + pkgs, err := p.List(namespace) + if err != nil { + return nil, fmt.Errorf("could not list packages in namespace %s", namespace) + } + + for _, pkg := range pkgs.Items { + if pkg.GetName() == name { + return &pkg, nil + } + } + + logger.Info("package not found") + return nil, nil +} + +func (p *RegistryProvider) List(namespace string) (*operators.PackageManifestList, error) { + logger := logrus.WithFields(logrus.Fields{ + "action": "List PackageManifests", + "namespace": namespace, + }) + + p.mu.RLock() + defer p.mu.RUnlock() + + pkgs := []operators.PackageManifest{} + for _, client := range p.clients { + if client.source.GetNamespace() == namespace || client.source.GetNamespace() == p.globalNamespace || namespace == metav1.NamespaceAll { + logger.Debugf("found CatalogSource %s", client.source.GetName()) + + stream, err := client.ListPackages(context.Background(), &api.ListPackageRequest{}) + if err != nil { + logger.WithField("err", err.Error()).Warnf("error getting stream") + continue + } + for { + pkgName, err := stream.Recv() + if err == io.EOF { + break + } + + if err != nil { + logger.WithField("err", err.Error()).Warnf("error getting data") + break + } + pkg, err := client.GetPackage(context.Background(), &api.GetPackageRequest{Name: pkgName.GetName()}) + if err != nil { + logger.WithField("err", err.Error()).Warnf("error getting package") + break + } + newPkg, err := toPackageManifest(pkg, client) + if err != nil { + logger.WithField("err", err.Error()).Warnf("error converting to packagemanifest") + break + } + + // Set request namespace to stop kube clients from complaining about global namespace mismatch. + newPkg.SetNamespace(namespace) + pkgs = append(pkgs, *newPkg) + } + } + } + + return &operators.PackageManifestList{Items: pkgs}, nil +} + +func toPackageManifest(pkg *api.Package, client registryClient) (*operators.PackageManifest, error) { + pkgChannels := pkg.GetChannels() + catsrc := client.source + manifest := &operators.PackageManifest{ + ObjectMeta: metav1.ObjectMeta{ + Name: pkg.GetName(), + Namespace: catsrc.GetNamespace(), + Labels: catsrc.GetLabels(), + CreationTimestamp: catsrc.GetCreationTimestamp(), + }, + Status: operators.PackageManifestStatus{ + CatalogSource: catsrc.GetName(), + CatalogSourceDisplayName: catsrc.Spec.DisplayName, + CatalogSourcePublisher: catsrc.Spec.Publisher, + CatalogSourceNamespace: catsrc.GetNamespace(), + PackageName: pkg.Name, + Channels: make([]operators.PackageChannel, len(pkgChannels)), + DefaultChannel: pkg.GetDefaultChannelName(), + }, + } + if manifest.GetLabels() == nil { + manifest.SetLabels(labels.Set{}) + } + manifest.ObjectMeta.Labels["catalog"] = manifest.Status.CatalogSource + manifest.ObjectMeta.Labels["catalog-namespace"] = manifest.Status.CatalogSourceNamespace + + for i, pkgChannel := range pkgChannels { + bundle, err := client.GetBundleForChannel(context.Background(), &api.GetBundleInChannelRequest{PkgName: pkg.GetName(), ChannelName: pkgChannel.GetName()}) + if err != nil { + return nil, err + } + + csv := operatorsv1alpha1.ClusterServiceVersion{} + err = json.Unmarshal([]byte(bundle.GetCsvJson()), &csv) + if err != nil { + return nil, err + } + manifest.Status.Channels[i] = operators.PackageChannel{ + Name: pkgChannel.GetName(), + CurrentCSV: csv.GetName(), + CurrentCSVDesc: operators.CreateCSVDescription(&csv), + } + + if manifest.Status.DefaultChannel != "" && csv.GetName() == manifest.Status.DefaultChannel || i == 0 { + manifest.Status.Provider = operators.AppLink{ + Name: csv.Spec.Provider.Name, + URL: csv.Spec.Provider.URL, + } + manifest.ObjectMeta.Labels["provider"] = manifest.Status.Provider.Name + manifest.ObjectMeta.Labels["provider-url"] = manifest.Status.Provider.URL + } + } + + return manifest, nil +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/server/server.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/server/server.go index e33555b171..1e1cbf85b2 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/server/server.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/server/server.go @@ -6,24 +6,21 @@ import ( "net" "time" - "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/provider" - - "github.com/spf13/cobra" - log "github.com/sirupsen/logrus" - genericapiserver "k8s.io/apiserver/pkg/server" + "github.com/spf13/cobra" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + genericserver "k8s.io/apiserver/pkg/server" genericoptions "k8s.io/apiserver/pkg/server/options" "k8s.io/client-go/informers" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" - "k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/clientcmd" "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client" - "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions" "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/queueinformer" "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apiserver" - genericpackagemanifests "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apiserver/generic" + genericpackageserver "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apiserver/generic" + "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/provider" ) // NewCommandStartPackageServer provides a CLI handler for 'start master' command @@ -63,10 +60,12 @@ type PackageServerOptions struct { Authorization *genericoptions.DelegatingAuthorizationOptions Features *genericoptions.FeatureOptions - WakeupInterval time.Duration + GlobalNamespace string WatchedNamespaces []string + WakeupInterval time.Duration - Kubeconfig string + Kubeconfig string + RegistryAddr string // Only to be used to for testing DisableAuthForTesting bool @@ -82,15 +81,16 @@ type PackageServerOptions struct { func NewPackageServerOptions(out, errOut io.Writer) *PackageServerOptions { o := &PackageServerOptions{ - SecureServing: genericoptions.WithLoopback(genericoptions.NewSecureServingOptions()), + SecureServing: genericoptions.NewSecureServingOptions().WithLoopback(), Authentication: genericoptions.NewDelegatingAuthenticationOptions(), Authorization: genericoptions.NewDelegatingAuthorizationOptions(), Features: genericoptions.NewFeatureOptions(), - WatchedNamespaces: []string{"local"}, + WatchedNamespaces: []string{v1.NamespaceAll}, WakeupInterval: 5 * time.Minute, - Debug: false, + DisableAuthForTesting: false, + Debug: false, StdOut: out, StdErr: errOut, @@ -108,8 +108,8 @@ func (o *PackageServerOptions) Config() (*apiserver.Config, error) { return nil, fmt.Errorf("error creating self-signed certificates: %v", err) } - serverConfig := genericapiserver.NewConfig(genericpackagemanifests.Codecs) - if err := o.SecureServing.ApplyTo(serverConfig); err != nil { + serverConfig := genericserver.NewConfig(genericpackageserver.Codecs) + if err := o.SecureServing.ApplyTo(&serverConfig.SecureServing, &serverConfig.LoopbackClientConfig); err != nil { return nil, err } @@ -124,12 +124,11 @@ func (o *PackageServerOptions) Config() (*apiserver.Config, error) { return &apiserver.Config{ GenericConfig: serverConfig, - ProviderConfig: genericpackagemanifests.ProviderConfig{}, + ProviderConfig: genericpackageserver.ProviderConfig{}, }, nil } func (o *PackageServerOptions) Run(stopCh <-chan struct{}) error { - // set debug log level if enabled if o.Debug { log.SetLevel(log.DebugLevel) } @@ -155,36 +154,22 @@ func (o *PackageServerOptions) Run(stopCh <-chan struct{}) error { return fmt.Errorf("unable to construct lister client config: %v", err) } - // set up the informers kubeClient, err := kubernetes.NewForConfig(clientConfig) if err != nil { return fmt.Errorf("unable to construct lister client: %v", err) } - // create a new client for OLM types (CRs) crClient, err := client.NewClient(o.Kubeconfig) if err != nil { return err } - log.Infof("package-server configured to watch namespaces %v", o.WatchedNamespaces) - - // Create an informer for each catalog namespace - catsrcSharedIndexInformers := []cache.SharedIndexInformer{} - for _, namespace := range o.WatchedNamespaces { - nsInformerFactory := externalversions.NewSharedInformerFactoryWithOptions(crClient, o.WakeupInterval, externalversions.WithNamespace(namespace)) - catsrcSharedIndexInformers = append(catsrcSharedIndexInformers, nsInformerFactory.Operators().V1alpha1().CatalogSources().Informer()) - } - - // Create a new queueinformer-based operator. - queueOperator, err := queueinformer.NewOperator(o.Kubeconfig) + queueOperator, err := queueinformer.NewOperator(o.Kubeconfig, log.New()) if err != nil { return err } - sourceProvider := provider.NewInMemoryProvider(catsrcSharedIndexInformers, queueOperator) - - // inject the providers into the config + sourceProvider := provider.NewRegistryProvider(crClient, queueOperator, o.WakeupInterval, o.WatchedNamespaces, o.GlobalNamespace) config.ProviderConfig.Provider = sourceProvider // we should never need to resync, since we're not worried about missing events, @@ -192,15 +177,20 @@ func (o *PackageServerOptions) Run(stopCh <-chan struct{}) error { // so set the default resync interval to 0 informerFactory := informers.NewSharedInformerFactory(kubeClient, 0) - // complete the config to get an API server server, err := config.Complete(informerFactory).New() if err != nil { return err } - // run the source provider's informers - go sourceProvider.Run(stopCh) + // Ensure that provider stops after the apiserver gracefully shuts down + provCh := make(chan struct{}) + ready, done, _ := sourceProvider.Run(provCh) + <-ready + + err = server.GenericAPIServer.PrepareRun().Run(stopCh) + go func() { provCh <- struct{}{} }() + + <-done - // run the apiserver - return server.GenericAPIServer.PrepareRun().Run(stopCh) + return err } diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/storage/packagemanifest/reststorage.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/storage/reststorage.go similarity index 52% rename from vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/storage/packagemanifest/reststorage.go rename to vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/storage/reststorage.go index 05decca232..6747752d2c 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/storage/packagemanifest/reststorage.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/storage/reststorage.go @@ -1,102 +1,122 @@ -package packagemanifest +package storage import ( "context" + "fmt" k8serrors "k8s.io/apimachinery/pkg/api/errors" metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" - genericapirequest "k8s.io/apiserver/pkg/endpoints/request" + genericreq "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/apiserver/pkg/registry/rest" - "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/packagemanifest/v1alpha1" + "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators" "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/provider" ) type PackageManifestStorage struct { groupResource schema.GroupResource prov provider.PackageManifestProvider + scheme *runtime.Scheme } -var _ rest.KindProvider = &PackageManifestStorage{} var _ rest.Storage = &PackageManifestStorage{} -var _ rest.Getter = &PackageManifestStorage{} +var _ rest.KindProvider = &PackageManifestStorage{} var _ rest.Lister = &PackageManifestStorage{} +var _ rest.Getter = &PackageManifestStorage{} var _ rest.Scoper = &PackageManifestStorage{} -// NewStorage returns an in-memory implementation of storage.Interface. -func NewStorage(groupResource schema.GroupResource, prov provider.PackageManifestProvider) *PackageManifestStorage { +// NewStorage returns a struct that implements methods needed for Kubernetes to satisfy API requests for the `PackageManifest` resource +func NewStorage(groupResource schema.GroupResource, prov provider.PackageManifestProvider, scheme *runtime.Scheme) *PackageManifestStorage { return &PackageManifestStorage{ groupResource: groupResource, prov: prov, + scheme: scheme, } } -// Storage interface +// New satisfies the Storage interface func (m *PackageManifestStorage) New() runtime.Object { - return &v1alpha1.PackageManifest{} + return &operators.PackageManifest{} } -// KindProvider interface +// Kind satisfies the KindProvider interface func (m *PackageManifestStorage) Kind() string { return "PackageManifest" } -// Lister interface +// NewList satisfies part of the Lister interface func (m *PackageManifestStorage) NewList() runtime.Object { - return &v1alpha1.PackageManifestList{} + return &operators.PackageManifestList{} } -// Lister interface +// List satisfies part of the Lister interface func (m *PackageManifestStorage) List(ctx context.Context, options *metainternalversion.ListOptions) (runtime.Object, error) { - // get namespace - namespace := genericapirequest.NamespaceValue(ctx) + namespace := genericreq.NamespaceValue(ctx) - // get selectors labelSelector := labels.Everything() if options != nil && options.LabelSelector != nil { labelSelector = options.LabelSelector } - res, err := m.prov.ListPackageManifests(namespace) + name, err := nameFor(options.FieldSelector) if err != nil { - return &v1alpha1.PackageManifestList{}, err + return nil, err } - // filter results by label - filtered := []v1alpha1.PackageManifest{} + res, err := m.prov.List(namespace) + if err != nil { + return nil, k8serrors.NewInternalError(err) + } + + // Filter by label selector + filtered := []operators.PackageManifest{} for _, manifest := range res.Items { - if labelSelector.Matches(labels.Set(manifest.GetLabels())) { + if matches(manifest, name, labelSelector) { filtered = append(filtered, manifest) } } - res.Items = filtered + return res, nil } -// Getter interface +// Get satisfies the Getter interface func (m *PackageManifestStorage) Get(ctx context.Context, name string, opts *metav1.GetOptions) (runtime.Object, error) { - namespace := genericapirequest.NamespaceValue(ctx) - manifest := v1alpha1.PackageManifest{} - - pm, err := m.prov.GetPackageManifest(namespace, name) - if err != nil { - return nil, err - } - if pm != nil { - manifest = *pm - } else { + namespace := genericreq.NamespaceValue(ctx) + manifest, err := m.prov.Get(namespace, name) + if err != nil || manifest == nil { return nil, k8serrors.NewNotFound(m.groupResource, name) } - return &manifest, nil + return manifest, nil } -// Scoper interface +// NamespaceScoped satisfies the Scoper interface func (m *PackageManifestStorage) NamespaceScoped() bool { return true } + +func nameFor(fs fields.Selector) (string, error) { + if fs == nil { + fs = fields.Everything() + } + name := "" + if value, found := fs.RequiresExactMatch("metadata.name"); found { + name = value + } else if !fs.Empty() { + return "", fmt.Errorf("field label not supported: %s", fs.Requirements()[0].Field) + } + return name, nil +} + +func matches(pm operators.PackageManifest, name string, ls labels.Selector) bool { + if name == "" { + name = pm.GetName() + } + return ls.Matches(labels.Set(pm.GetLabels())) && pm.GetName() == name +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/version/version.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/version/version.go index b330d47a04..190b80f438 100644 --- a/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/version/version.go +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/version/version.go @@ -12,3 +12,8 @@ var GitCommit string func String() string { return fmt.Sprintf("OLM version: %s\ngit commit: %s\n", OLMVersion, GitCommit) } + +// Full returns a hypenated concatenation of just OLMVersion and GitCommit +func Full() string { + return fmt.Sprintf("%s-%s", OLMVersion, GitCommit) +} diff --git a/vendor/github.com/operator-framework/operator-lifecycle-manager/tools.go b/vendor/github.com/operator-framework/operator-lifecycle-manager/tools.go new file mode 100644 index 0000000000..c853201e6d --- /dev/null +++ b/vendor/github.com/operator-framework/operator-lifecycle-manager/tools.go @@ -0,0 +1,19 @@ +// +build tools + +package tools + +import ( + _ "github.com/golang/mock/mockgen" + _ "github.com/maxbrunsfeld/counterfeiter" + _ "k8s.io/code-generator/cmd/client-gen" + _ "k8s.io/code-generator/cmd/conversion-gen/" + _ "k8s.io/code-generator/cmd/deepcopy-gen" + _ "k8s.io/code-generator/cmd/defaulter-gen" + _ "k8s.io/code-generator/cmd/go-to-protobuf" + _ "k8s.io/code-generator/cmd/import-boss" + _ "k8s.io/code-generator/cmd/informer-gen" + _ "k8s.io/code-generator/cmd/lister-gen" + _ "k8s.io/code-generator/cmd/openapi-gen" + _ "k8s.io/code-generator/cmd/set-gen" + _ "k8s.io/kube-openapi/cmd/openapi-gen" +) diff --git a/vendor/k8s.io/utils/LICENSE b/vendor/k8s.io/utils/LICENSE new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/vendor/k8s.io/utils/LICENSE @@ -0,0 +1,202 @@ + + 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 + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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/vendor/k8s.io/utils/buffer/ring_growing.go b/vendor/k8s.io/utils/buffer/ring_growing.go new file mode 100644 index 0000000000..86965a5131 --- /dev/null +++ b/vendor/k8s.io/utils/buffer/ring_growing.go @@ -0,0 +1,72 @@ +/* +Copyright 2017 The Kubernetes 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. +*/ + +package buffer + +// RingGrowing is a growing ring buffer. +// Not thread safe. +type RingGrowing struct { + data []interface{} + n int // Size of Data + beg int // First available element + readable int // Number of data items available +} + +// NewRingGrowing constructs a new RingGrowing instance with provided parameters. +func NewRingGrowing(initialSize int) *RingGrowing { + return &RingGrowing{ + data: make([]interface{}, initialSize), + n: initialSize, + } +} + +// ReadOne reads (consumes) first item from the buffer if it is available, otherwise returns false. +func (r *RingGrowing) ReadOne() (data interface{}, ok bool) { + if r.readable == 0 { + return nil, false + } + r.readable-- + element := r.data[r.beg] + r.data[r.beg] = nil // Remove reference to the object to help GC + if r.beg == r.n-1 { + // Was the last element + r.beg = 0 + } else { + r.beg++ + } + return element, true +} + +// WriteOne adds an item to the end of the buffer, growing it if it is full. +func (r *RingGrowing) WriteOne(data interface{}) { + if r.readable == r.n { + // Time to grow + newN := r.n * 2 + newData := make([]interface{}, newN) + to := r.beg + r.readable + if to <= r.n { + copy(newData, r.data[r.beg:to]) + } else { + copied := copy(newData, r.data[r.beg:]) + copy(newData[copied:], r.data[:(to%r.n)]) + } + r.beg = 0 + r.data = newData + r.n = newN + } + r.data[(r.readable+r.beg)%r.n] = data + r.readable++ +} diff --git a/vendor/k8s.io/utils/clock/clock.go b/vendor/k8s.io/utils/clock/clock.go new file mode 100644 index 0000000000..789c0238c8 --- /dev/null +++ b/vendor/k8s.io/utils/clock/clock.go @@ -0,0 +1,97 @@ +/* +Copyright 2014 The Kubernetes 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. +*/ + +package clock + +import "time" + +// Clock allows for injecting fake or real clocks into code that +// needs to do arbitrary things based on time. +type Clock interface { + Now() time.Time + Since(time.Time) time.Duration + After(d time.Duration) <-chan time.Time + NewTimer(d time.Duration) Timer + Sleep(d time.Duration) + Tick(d time.Duration) <-chan time.Time +} + +var _ = Clock(RealClock{}) + +// RealClock really calls time.Now() +type RealClock struct{} + +// Now returns the current time. +func (RealClock) Now() time.Time { + return time.Now() +} + +// Since returns time since the specified timestamp. +func (RealClock) Since(ts time.Time) time.Duration { + return time.Since(ts) +} + +// After is the same as time.After(d). +func (RealClock) After(d time.Duration) <-chan time.Time { + return time.After(d) +} + +// NewTimer is the same as time.NewTimer(d) +func (RealClock) NewTimer(d time.Duration) Timer { + return &realTimer{ + timer: time.NewTimer(d), + } +} + +// Tick is the same as time.Tick(d) +func (RealClock) Tick(d time.Duration) <-chan time.Time { + return time.Tick(d) +} + +// Sleep is the same as time.Sleep(d) +func (RealClock) Sleep(d time.Duration) { + time.Sleep(d) +} + +// Timer allows for injecting fake or real timers into code that +// needs to do arbitrary things based on time. +type Timer interface { + C() <-chan time.Time + Stop() bool + Reset(d time.Duration) bool +} + +var _ = Timer(&realTimer{}) + +// realTimer is backed by an actual time.Timer. +type realTimer struct { + timer *time.Timer +} + +// C returns the underlying timer's channel. +func (r *realTimer) C() <-chan time.Time { + return r.timer.C +} + +// Stop calls Stop() on the underlying timer. +func (r *realTimer) Stop() bool { + return r.timer.Stop() +} + +// Reset calls Reset() on the underlying timer. +func (r *realTimer) Reset(d time.Duration) bool { + return r.timer.Reset(d) +} diff --git a/vendor/k8s.io/utils/clock/testing/fake_clock.go b/vendor/k8s.io/utils/clock/testing/fake_clock.go new file mode 100644 index 0000000000..2fc34aed6d --- /dev/null +++ b/vendor/k8s.io/utils/clock/testing/fake_clock.go @@ -0,0 +1,274 @@ +/* +Copyright 2014 The Kubernetes 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. +*/ + +package testing + +import ( + "sync" + "time" + + "k8s.io/utils/clock" +) + +var ( + _ = clock.Clock(&FakeClock{}) + _ = clock.Clock(&IntervalClock{}) +) + +// FakeClock implements clock.Clock, but returns an arbitrary time. +type FakeClock struct { + lock sync.RWMutex + time time.Time + + // waiters are waiting for the fake time to pass their specified time + waiters []*fakeClockWaiter +} + +type fakeClockWaiter struct { + targetTime time.Time + stepInterval time.Duration + skipIfBlocked bool + destChan chan time.Time + fired bool +} + +// NewFakeClock constructs a fake clock set to the provided time. +func NewFakeClock(t time.Time) *FakeClock { + return &FakeClock{ + time: t, + } +} + +// Now returns f's time. +func (f *FakeClock) Now() time.Time { + f.lock.RLock() + defer f.lock.RUnlock() + return f.time +} + +// Since returns time since the time in f. +func (f *FakeClock) Since(ts time.Time) time.Duration { + f.lock.RLock() + defer f.lock.RUnlock() + return f.time.Sub(ts) +} + +// After is the fake version of time.After(d). +func (f *FakeClock) After(d time.Duration) <-chan time.Time { + f.lock.Lock() + defer f.lock.Unlock() + stopTime := f.time.Add(d) + ch := make(chan time.Time, 1) // Don't block! + f.waiters = append(f.waiters, &fakeClockWaiter{ + targetTime: stopTime, + destChan: ch, + }) + return ch +} + +// NewTimer constructs a fake timer, akin to time.NewTimer(d). +func (f *FakeClock) NewTimer(d time.Duration) clock.Timer { + f.lock.Lock() + defer f.lock.Unlock() + stopTime := f.time.Add(d) + ch := make(chan time.Time, 1) // Don't block! + timer := &fakeTimer{ + fakeClock: f, + waiter: fakeClockWaiter{ + targetTime: stopTime, + destChan: ch, + }, + } + f.waiters = append(f.waiters, &timer.waiter) + return timer +} + +// Tick constructs a fake ticker, akin to time.Tick +func (f *FakeClock) Tick(d time.Duration) <-chan time.Time { + if d <= 0 { + return nil + } + f.lock.Lock() + defer f.lock.Unlock() + tickTime := f.time.Add(d) + ch := make(chan time.Time, 1) // hold one tick + f.waiters = append(f.waiters, &fakeClockWaiter{ + targetTime: tickTime, + stepInterval: d, + skipIfBlocked: true, + destChan: ch, + }) + + return ch +} + +// Step moves the clock by Duration and notifies anyone that's called After, +// Tick, or NewTimer. +func (f *FakeClock) Step(d time.Duration) { + f.lock.Lock() + defer f.lock.Unlock() + f.setTimeLocked(f.time.Add(d)) +} + +// SetTime sets the time. +func (f *FakeClock) SetTime(t time.Time) { + f.lock.Lock() + defer f.lock.Unlock() + f.setTimeLocked(t) +} + +// Actually changes the time and checks any waiters. f must be write-locked. +func (f *FakeClock) setTimeLocked(t time.Time) { + f.time = t + newWaiters := make([]*fakeClockWaiter, 0, len(f.waiters)) + for i := range f.waiters { + w := f.waiters[i] + if !w.targetTime.After(t) { + + if w.skipIfBlocked { + select { + case w.destChan <- t: + w.fired = true + default: + } + } else { + w.destChan <- t + w.fired = true + } + + if w.stepInterval > 0 { + for !w.targetTime.After(t) { + w.targetTime = w.targetTime.Add(w.stepInterval) + } + newWaiters = append(newWaiters, w) + } + + } else { + newWaiters = append(newWaiters, f.waiters[i]) + } + } + f.waiters = newWaiters +} + +// HasWaiters returns true if After has been called on f but not yet satisfied (so you can +// write race-free tests). +func (f *FakeClock) HasWaiters() bool { + f.lock.RLock() + defer f.lock.RUnlock() + return len(f.waiters) > 0 +} + +// Sleep is akin to time.Sleep +func (f *FakeClock) Sleep(d time.Duration) { + f.Step(d) +} + +// IntervalClock implements clock.Clock, but each invocation of Now steps the clock forward the specified duration +type IntervalClock struct { + Time time.Time + Duration time.Duration +} + +// Now returns i's time. +func (i *IntervalClock) Now() time.Time { + i.Time = i.Time.Add(i.Duration) + return i.Time +} + +// Since returns time since the time in i. +func (i *IntervalClock) Since(ts time.Time) time.Duration { + return i.Time.Sub(ts) +} + +// After is unimplemented, will panic. +// TODO: make interval clock use FakeClock so this can be implemented. +func (*IntervalClock) After(d time.Duration) <-chan time.Time { + panic("IntervalClock doesn't implement After") +} + +// NewTimer is unimplemented, will panic. +// TODO: make interval clock use FakeClock so this can be implemented. +func (*IntervalClock) NewTimer(d time.Duration) clock.Timer { + panic("IntervalClock doesn't implement NewTimer") +} + +// Tick is unimplemented, will panic. +// TODO: make interval clock use FakeClock so this can be implemented. +func (*IntervalClock) Tick(d time.Duration) <-chan time.Time { + panic("IntervalClock doesn't implement Tick") +} + +// Sleep is unimplemented, will panic. +func (*IntervalClock) Sleep(d time.Duration) { + panic("IntervalClock doesn't implement Sleep") +} + +var _ = clock.Timer(&fakeTimer{}) + +// fakeTimer implements clock.Timer based on a FakeClock. +type fakeTimer struct { + fakeClock *FakeClock + waiter fakeClockWaiter +} + +// C returns the channel that notifies when this timer has fired. +func (f *fakeTimer) C() <-chan time.Time { + return f.waiter.destChan +} + +// Stop stops the timer and returns true if the timer has not yet fired, or false otherwise. +func (f *fakeTimer) Stop() bool { + f.fakeClock.lock.Lock() + defer f.fakeClock.lock.Unlock() + + newWaiters := make([]*fakeClockWaiter, 0, len(f.fakeClock.waiters)) + for i := range f.fakeClock.waiters { + w := f.fakeClock.waiters[i] + if w != &f.waiter { + newWaiters = append(newWaiters, w) + } + } + + f.fakeClock.waiters = newWaiters + + return !f.waiter.fired +} + +// Reset resets the timer to the fake clock's "now" + d. It returns true if the timer has not yet +// fired, or false otherwise. +func (f *fakeTimer) Reset(d time.Duration) bool { + f.fakeClock.lock.Lock() + defer f.fakeClock.lock.Unlock() + + active := !f.waiter.fired + + f.waiter.fired = false + f.waiter.targetTime = f.fakeClock.time.Add(d) + + var isWaiting bool + for i := range f.fakeClock.waiters { + w := f.fakeClock.waiters[i] + if w == &f.waiter { + isWaiting = true + break + } + } + if !isWaiting { + f.fakeClock.waiters = append(f.fakeClock.waiters, &f.waiter) + } + + return active +} diff --git a/vendor/k8s.io/utils/diff/diff.go b/vendor/k8s.io/utils/diff/diff.go new file mode 100644 index 0000000000..2a6e3aebd4 --- /dev/null +++ b/vendor/k8s.io/utils/diff/diff.go @@ -0,0 +1,314 @@ +/* +Copyright 2014 The Kubernetes 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. +*/ + +package diff + +import ( + "bytes" + "encoding/json" + "fmt" + "reflect" + "sort" + "strings" + "text/tabwriter" + + "github.com/davecgh/go-spew/spew" + + "k8s.io/utils/field" +) + +// StringDiff diffs a and b and returns a human readable diff. +func StringDiff(a, b string) string { + ba := []byte(a) + bb := []byte(b) + out := []byte{} + i := 0 + for ; i < len(ba) && i < len(bb); i++ { + if ba[i] != bb[i] { + break + } + out = append(out, ba[i]) + } + out = append(out, []byte("\n\nA: ")...) + out = append(out, ba[i:]...) + out = append(out, []byte("\n\nB: ")...) + out = append(out, bb[i:]...) + out = append(out, []byte("\n\n")...) + return string(out) +} + +// ObjectDiff writes the two objects out as JSON and prints out the identical part of +// the objects followed by the remaining part of 'a' and finally the remaining part of 'b'. +// For debugging tests. +func ObjectDiff(a, b interface{}) string { + ab, err := json.Marshal(a) + if err != nil { + panic(fmt.Sprintf("a: %v", err)) + } + bb, err := json.Marshal(b) + if err != nil { + panic(fmt.Sprintf("b: %v", err)) + } + return StringDiff(string(ab), string(bb)) +} + +// ObjectGoPrintDiff is like ObjectDiff, but uses go-spew to print the objects, +// which shows absolutely everything by recursing into every single pointer +// (go's %#v formatters OTOH stop at a certain point). This is needed when you +// can't figure out why reflect.DeepEqual is returning false and nothing is +// showing you differences. This will. +func ObjectGoPrintDiff(a, b interface{}) string { + s := spew.ConfigState{DisableMethods: true} + return StringDiff( + s.Sprintf("%#v", a), + s.Sprintf("%#v", b), + ) +} + +// ObjectReflectDiff returns a diff computed through reflection, without serializing to JSON. +func ObjectReflectDiff(a, b interface{}) string { + vA, vB := reflect.ValueOf(a), reflect.ValueOf(b) + if vA.Type() != vB.Type() { + return fmt.Sprintf("type A %T and type B %T do not match", a, b) + } + diffs := objectReflectDiff(field.NewPath("object"), vA, vB) + if len(diffs) == 0 { + return "" + } + out := []string{""} + for _, d := range diffs { + elidedA, elidedB := limit(d.a, d.b, 80) + out = append(out, + fmt.Sprintf("%s:", d.path), + fmt.Sprintf(" a: %s", elidedA), + fmt.Sprintf(" b: %s", elidedB), + ) + } + return strings.Join(out, "\n") +} + +// limit: +// 1. stringifies aObj and bObj +// 2. elides identical prefixes if either is too long +// 3. elides remaining content from the end if either is too long +func limit(aObj, bObj interface{}, max int) (string, string) { + elidedPrefix := "" + elidedASuffix := "" + elidedBSuffix := "" + a, b := fmt.Sprintf("%#v", aObj), fmt.Sprintf("%#v", bObj) + + if aObj != nil && bObj != nil { + if aType, bType := fmt.Sprintf("%T", aObj), fmt.Sprintf("%T", bObj); aType != bType { + a = fmt.Sprintf("%s (%s)", a, aType) + b = fmt.Sprintf("%s (%s)", b, bType) + } + } + + for { + switch { + case len(a) > max && len(a) > 4 && len(b) > 4 && a[:4] == b[:4]: + // a is too long, b has data, and the first several characters are the same + elidedPrefix = "..." + a = a[2:] + b = b[2:] + + case len(b) > max && len(b) > 4 && len(a) > 4 && a[:4] == b[:4]: + // b is too long, a has data, and the first several characters are the same + elidedPrefix = "..." + a = a[2:] + b = b[2:] + + case len(a) > max: + a = a[:max] + elidedASuffix = "..." + + case len(b) > max: + b = b[:max] + elidedBSuffix = "..." + + default: + // both are short enough + return elidedPrefix + a + elidedASuffix, elidedPrefix + b + elidedBSuffix + } + } +} + +func public(s string) bool { + if len(s) == 0 { + return false + } + return s[:1] == strings.ToUpper(s[:1]) +} + +type diff struct { + path *field.Path + a, b interface{} +} + +type orderedDiffs []diff + +func (d orderedDiffs) Len() int { return len(d) } +func (d orderedDiffs) Swap(i, j int) { d[i], d[j] = d[j], d[i] } +func (d orderedDiffs) Less(i, j int) bool { + a, b := d[i].path.String(), d[j].path.String() + if a < b { + return true + } + return false +} + +func objectReflectDiff(path *field.Path, a, b reflect.Value) []diff { + switch a.Type().Kind() { + case reflect.Struct: + var changes []diff + for i := 0; i < a.Type().NumField(); i++ { + if !public(a.Type().Field(i).Name) { + if reflect.DeepEqual(a.Interface(), b.Interface()) { + continue + } + return []diff{{path: path, a: fmt.Sprintf("%#v", a), b: fmt.Sprintf("%#v", b)}} + } + if sub := objectReflectDiff(path.Child(a.Type().Field(i).Name), a.Field(i), b.Field(i)); len(sub) > 0 { + changes = append(changes, sub...) + } + } + return changes + case reflect.Ptr, reflect.Interface: + if a.IsNil() || b.IsNil() { + switch { + case a.IsNil() && b.IsNil(): + return nil + case a.IsNil(): + return []diff{{path: path, a: nil, b: b.Interface()}} + default: + return []diff{{path: path, a: a.Interface(), b: nil}} + } + } + return objectReflectDiff(path, a.Elem(), b.Elem()) + case reflect.Chan: + if !reflect.DeepEqual(a.Interface(), b.Interface()) { + return []diff{{path: path, a: a.Interface(), b: b.Interface()}} + } + return nil + case reflect.Slice: + lA, lB := a.Len(), b.Len() + l := lA + if lB < lA { + l = lB + } + if lA == lB && lA == 0 { + if a.IsNil() != b.IsNil() { + return []diff{{path: path, a: a.Interface(), b: b.Interface()}} + } + return nil + } + var diffs []diff + for i := 0; i < l; i++ { + if !reflect.DeepEqual(a.Index(i), b.Index(i)) { + diffs = append(diffs, objectReflectDiff(path.Index(i), a.Index(i), b.Index(i))...) + } + } + for i := l; i < lA; i++ { + diffs = append(diffs, diff{path: path.Index(i), a: a.Index(i), b: nil}) + } + for i := l; i < lB; i++ { + diffs = append(diffs, diff{path: path.Index(i), a: nil, b: b.Index(i)}) + } + return diffs + case reflect.Map: + if reflect.DeepEqual(a.Interface(), b.Interface()) { + return nil + } + aKeys := make(map[interface{}]interface{}) + for _, key := range a.MapKeys() { + aKeys[key.Interface()] = a.MapIndex(key).Interface() + } + var missing []diff + for _, key := range b.MapKeys() { + if _, ok := aKeys[key.Interface()]; ok { + delete(aKeys, key.Interface()) + if reflect.DeepEqual(a.MapIndex(key).Interface(), b.MapIndex(key).Interface()) { + continue + } + missing = append(missing, objectReflectDiff(path.Key(fmt.Sprintf("%s", key.Interface())), a.MapIndex(key), b.MapIndex(key))...) + continue + } + missing = append(missing, diff{path: path.Key(fmt.Sprintf("%s", key.Interface())), a: nil, b: b.MapIndex(key).Interface()}) + } + for key, value := range aKeys { + missing = append(missing, diff{path: path.Key(fmt.Sprintf("%s", key)), a: value, b: nil}) + } + if len(missing) == 0 { + missing = append(missing, diff{path: path, a: a.Interface(), b: b.Interface()}) + } + sort.Sort(orderedDiffs(missing)) + return missing + default: + if reflect.DeepEqual(a.Interface(), b.Interface()) { + return nil + } + if !a.CanInterface() { + return []diff{{path: path, a: fmt.Sprintf("%#v", a), b: fmt.Sprintf("%#v", b)}} + } + return []diff{{path: path, a: a.Interface(), b: b.Interface()}} + } +} + +// ObjectGoPrintSideBySide prints a and b as textual dumps side by side, +// enabling easy visual scanning for mismatches. +func ObjectGoPrintSideBySide(a, b interface{}) string { + s := spew.ConfigState{ + Indent: " ", + // Extra deep spew. + DisableMethods: true, + } + sA := s.Sdump(a) + sB := s.Sdump(b) + + linesA := strings.Split(sA, "\n") + linesB := strings.Split(sB, "\n") + width := 0 + for _, s := range linesA { + l := len(s) + if l > width { + width = l + } + } + for _, s := range linesB { + l := len(s) + if l > width { + width = l + } + } + buf := &bytes.Buffer{} + w := tabwriter.NewWriter(buf, width, 0, 1, ' ', 0) + max := len(linesA) + if len(linesB) > max { + max = len(linesB) + } + for i := 0; i < max; i++ { + var a, b string + if i < len(linesA) { + a = linesA[i] + } + if i < len(linesB) { + b = linesB[i] + } + fmt.Fprintf(w, "%s\t%s\n", a, b) + } + w.Flush() + return buf.String() +} diff --git a/vendor/k8s.io/utils/exec/doc.go b/vendor/k8s.io/utils/exec/doc.go new file mode 100644 index 0000000000..cbb44bdb5d --- /dev/null +++ b/vendor/k8s.io/utils/exec/doc.go @@ -0,0 +1,18 @@ +/* +Copyright 2017 The Kubernetes 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. +*/ + +// Package exec provides an injectable interface and implementations for running commands. +package exec // import "k8s.io/utils/exec" diff --git a/vendor/k8s.io/utils/exec/exec.go b/vendor/k8s.io/utils/exec/exec.go new file mode 100644 index 0000000000..96bec01ca8 --- /dev/null +++ b/vendor/k8s.io/utils/exec/exec.go @@ -0,0 +1,252 @@ +/* +Copyright 2017 The Kubernetes 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. +*/ + +package exec + +import ( + "context" + "io" + osexec "os/exec" + "syscall" + "time" +) + +// ErrExecutableNotFound is returned if the executable is not found. +var ErrExecutableNotFound = osexec.ErrNotFound + +// Interface is an interface that presents a subset of the os/exec API. Use this +// when you want to inject fakeable/mockable exec behavior. +type Interface interface { + // Command returns a Cmd instance which can be used to run a single command. + // This follows the pattern of package os/exec. + Command(cmd string, args ...string) Cmd + + // CommandContext returns a Cmd instance which can be used to run a single command. + // + // The provided context is used to kill the process if the context becomes done + // before the command completes on its own. For example, a timeout can be set in + // the context. + CommandContext(ctx context.Context, cmd string, args ...string) Cmd + + // LookPath wraps os/exec.LookPath + LookPath(file string) (string, error) +} + +// Cmd is an interface that presents an API that is very similar to Cmd from os/exec. +// As more functionality is needed, this can grow. Since Cmd is a struct, we will have +// to replace fields with get/set method pairs. +type Cmd interface { + // Run runs the command to the completion. + Run() error + // CombinedOutput runs the command and returns its combined standard output + // and standard error. This follows the pattern of package os/exec. + CombinedOutput() ([]byte, error) + // Output runs the command and returns standard output, but not standard err + Output() ([]byte, error) + SetDir(dir string) + SetStdin(in io.Reader) + SetStdout(out io.Writer) + SetStderr(out io.Writer) + SetEnv(env []string) + + // StdoutPipe and StderrPipe for getting the process' Stdout and Stderr as + // Readers + StdoutPipe() (io.ReadCloser, error) + StderrPipe() (io.ReadCloser, error) + + // Start and Wait are for running a process non-blocking + Start() error + Wait() error + + // Stops the command by sending SIGTERM. It is not guaranteed the + // process will stop before this function returns. If the process is not + // responding, an internal timer function will send a SIGKILL to force + // terminate after 10 seconds. + Stop() +} + +// ExitError is an interface that presents an API similar to os.ProcessState, which is +// what ExitError from os/exec is. This is designed to make testing a bit easier and +// probably loses some of the cross-platform properties of the underlying library. +type ExitError interface { + String() string + Error() string + Exited() bool + ExitStatus() int +} + +// Implements Interface in terms of really exec()ing. +type executor struct{} + +// New returns a new Interface which will os/exec to run commands. +func New() Interface { + return &executor{} +} + +// Command is part of the Interface interface. +func (executor *executor) Command(cmd string, args ...string) Cmd { + return (*cmdWrapper)(osexec.Command(cmd, args...)) +} + +// CommandContext is part of the Interface interface. +func (executor *executor) CommandContext(ctx context.Context, cmd string, args ...string) Cmd { + return (*cmdWrapper)(osexec.CommandContext(ctx, cmd, args...)) +} + +// LookPath is part of the Interface interface +func (executor *executor) LookPath(file string) (string, error) { + return osexec.LookPath(file) +} + +// Wraps exec.Cmd so we can capture errors. +type cmdWrapper osexec.Cmd + +var _ Cmd = &cmdWrapper{} + +func (cmd *cmdWrapper) SetDir(dir string) { + cmd.Dir = dir +} + +func (cmd *cmdWrapper) SetStdin(in io.Reader) { + cmd.Stdin = in +} + +func (cmd *cmdWrapper) SetStdout(out io.Writer) { + cmd.Stdout = out +} + +func (cmd *cmdWrapper) SetStderr(out io.Writer) { + cmd.Stderr = out +} + +func (cmd *cmdWrapper) SetEnv(env []string) { + cmd.Env = env +} + +func (cmd *cmdWrapper) StdoutPipe() (io.ReadCloser, error) { + r, err := (*osexec.Cmd)(cmd).StdoutPipe() + return r, handleError(err) +} + +func (cmd *cmdWrapper) StderrPipe() (io.ReadCloser, error) { + r, err := (*osexec.Cmd)(cmd).StderrPipe() + return r, handleError(err) +} + +func (cmd *cmdWrapper) Start() error { + err := (*osexec.Cmd)(cmd).Start() + return handleError(err) +} + +func (cmd *cmdWrapper) Wait() error { + err := (*osexec.Cmd)(cmd).Wait() + return handleError(err) +} + +// Run is part of the Cmd interface. +func (cmd *cmdWrapper) Run() error { + err := (*osexec.Cmd)(cmd).Run() + return handleError(err) +} + +// CombinedOutput is part of the Cmd interface. +func (cmd *cmdWrapper) CombinedOutput() ([]byte, error) { + out, err := (*osexec.Cmd)(cmd).CombinedOutput() + return out, handleError(err) +} + +func (cmd *cmdWrapper) Output() ([]byte, error) { + out, err := (*osexec.Cmd)(cmd).Output() + return out, handleError(err) +} + +// Stop is part of the Cmd interface. +func (cmd *cmdWrapper) Stop() { + c := (*osexec.Cmd)(cmd) + + if c.Process == nil { + return + } + + c.Process.Signal(syscall.SIGTERM) + + time.AfterFunc(10*time.Second, func() { + if !c.ProcessState.Exited() { + c.Process.Signal(syscall.SIGKILL) + } + }) +} + +func handleError(err error) error { + if err == nil { + return nil + } + + switch e := err.(type) { + case *osexec.ExitError: + return &ExitErrorWrapper{e} + case *osexec.Error: + if e.Err == osexec.ErrNotFound { + return ErrExecutableNotFound + } + } + + return err +} + +// ExitErrorWrapper is an implementation of ExitError in terms of os/exec ExitError. +// Note: standard exec.ExitError is type *os.ProcessState, which already implements Exited(). +type ExitErrorWrapper struct { + *osexec.ExitError +} + +var _ ExitError = &ExitErrorWrapper{} + +// ExitStatus is part of the ExitError interface. +func (eew ExitErrorWrapper) ExitStatus() int { + ws, ok := eew.Sys().(syscall.WaitStatus) + if !ok { + panic("can't call ExitStatus() on a non-WaitStatus exitErrorWrapper") + } + return ws.ExitStatus() +} + +// CodeExitError is an implementation of ExitError consisting of an error object +// and an exit code (the upper bits of os.exec.ExitStatus). +type CodeExitError struct { + Err error + Code int +} + +var _ ExitError = CodeExitError{} + +func (e CodeExitError) Error() string { + return e.Err.Error() +} + +func (e CodeExitError) String() string { + return e.Err.Error() +} + +// Exited is to check if the process has finished +func (e CodeExitError) Exited() bool { + return true +} + +// ExitStatus is for checking the error code +func (e CodeExitError) ExitStatus() int { + return e.Code +} diff --git a/vendor/k8s.io/utils/exec/testing/fake_exec.go b/vendor/k8s.io/utils/exec/testing/fake_exec.go new file mode 100644 index 0000000000..66b5de8b31 --- /dev/null +++ b/vendor/k8s.io/utils/exec/testing/fake_exec.go @@ -0,0 +1,217 @@ +/* +Copyright 2017 The Kubernetes 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. +*/ + +package testingexec + +import ( + "context" + "fmt" + "io" + + "k8s.io/utils/exec" +) + +// FakeExec is a simple scripted Interface type. +type FakeExec struct { + CommandScript []FakeCommandAction + CommandCalls int + LookPathFunc func(string) (string, error) +} + +var _ exec.Interface = &FakeExec{} + +// FakeCommandAction is the function to be executed +type FakeCommandAction func(cmd string, args ...string) exec.Cmd + +// Command is to track the commands that are executed +func (fake *FakeExec) Command(cmd string, args ...string) exec.Cmd { + if fake.CommandCalls > len(fake.CommandScript)-1 { + panic(fmt.Sprintf("ran out of Command() actions. Could not handle command [%d]: %s args: %v", fake.CommandCalls, cmd, args)) + } + i := fake.CommandCalls + fake.CommandCalls++ + return fake.CommandScript[i](cmd, args...) +} + +// CommandContext wraps arguments into exec.Cmd +func (fake *FakeExec) CommandContext(ctx context.Context, cmd string, args ...string) exec.Cmd { + return fake.Command(cmd, args...) +} + +// LookPath is for finding the path of a file +func (fake *FakeExec) LookPath(file string) (string, error) { + return fake.LookPathFunc(file) +} + +// FakeCmd is a simple scripted Cmd type. +type FakeCmd struct { + Argv []string + CombinedOutputScript []FakeCombinedOutputAction + CombinedOutputCalls int + CombinedOutputLog [][]string + RunScript []FakeRunAction + RunCalls int + RunLog [][]string + Dirs []string + Stdin io.Reader + Stdout io.Writer + Stderr io.Writer + Env []string + StdoutPipeResponse FakeStdIOPipeResponse + StderrPipeResponse FakeStdIOPipeResponse + WaitResponse error + StartResponse error +} + +var _ exec.Cmd = &FakeCmd{} + +// InitFakeCmd is for creating a fake exec.Cmd +func InitFakeCmd(fake *FakeCmd, cmd string, args ...string) exec.Cmd { + fake.Argv = append([]string{cmd}, args...) + return fake +} + +// FakeStdIOPipeResponse holds responses to use as fakes for the StdoutPipe and +// StderrPipe method calls +type FakeStdIOPipeResponse struct { + ReadCloser io.ReadCloser + Error error +} + +// FakeCombinedOutputAction is a function type +type FakeCombinedOutputAction func() ([]byte, error) + +// FakeRunAction is a function type +type FakeRunAction func() ([]byte, []byte, error) + +// SetDir sets the directory +func (fake *FakeCmd) SetDir(dir string) { + fake.Dirs = append(fake.Dirs, dir) +} + +// SetStdin sets the stdin +func (fake *FakeCmd) SetStdin(in io.Reader) { + fake.Stdin = in +} + +// SetStdout sets the stdout +func (fake *FakeCmd) SetStdout(out io.Writer) { + fake.Stdout = out +} + +// SetStderr sets the stderr +func (fake *FakeCmd) SetStderr(out io.Writer) { + fake.Stderr = out +} + +// SetEnv sets the environment variables +func (fake *FakeCmd) SetEnv(env []string) { + fake.Env = env +} + +// StdoutPipe returns an injected ReadCloser & error (via StdoutPipeResponse) +// to be able to inject an output stream on Stdout +func (fake *FakeCmd) StdoutPipe() (io.ReadCloser, error) { + return fake.StdoutPipeResponse.ReadCloser, fake.StdoutPipeResponse.Error +} + +// StderrPipe returns an injected ReadCloser & error (via StderrPipeResponse) +// to be able to inject an output stream on Stderr +func (fake *FakeCmd) StderrPipe() (io.ReadCloser, error) { + return fake.StderrPipeResponse.ReadCloser, fake.StderrPipeResponse.Error +} + +// Start mimicks starting the process (in the background) and returns the +// injected StartResponse +func (fake *FakeCmd) Start() error { + return fake.StartResponse +} + +// Wait mimicks waiting for the process to exit returns the +// injected WaitResponse +func (fake *FakeCmd) Wait() error { + return fake.WaitResponse +} + +// Run sets runs the command +func (fake *FakeCmd) Run() error { + if fake.RunCalls > len(fake.RunScript)-1 { + panic("ran out of Run() actions") + } + if fake.RunLog == nil { + fake.RunLog = [][]string{} + } + i := fake.RunCalls + fake.RunLog = append(fake.RunLog, append([]string{}, fake.Argv...)) + fake.RunCalls++ + stdout, stderr, err := fake.RunScript[i]() + if stdout != nil { + fake.Stdout.Write(stdout) + } + if stderr != nil { + fake.Stderr.Write(stderr) + } + return err +} + +// CombinedOutput returns the output from the command +func (fake *FakeCmd) CombinedOutput() ([]byte, error) { + if fake.CombinedOutputCalls > len(fake.CombinedOutputScript)-1 { + panic("ran out of CombinedOutput() actions") + } + if fake.CombinedOutputLog == nil { + fake.CombinedOutputLog = [][]string{} + } + i := fake.CombinedOutputCalls + fake.CombinedOutputLog = append(fake.CombinedOutputLog, append([]string{}, fake.Argv...)) + fake.CombinedOutputCalls++ + return fake.CombinedOutputScript[i]() +} + +// Output is the response from the command +func (fake *FakeCmd) Output() ([]byte, error) { + return nil, fmt.Errorf("unimplemented") +} + +// Stop is to stop the process +func (fake *FakeCmd) Stop() { + // no-op +} + +// FakeExitError is a simple fake ExitError type. +type FakeExitError struct { + Status int +} + +var _ exec.ExitError = FakeExitError{} + +func (fake FakeExitError) String() string { + return fmt.Sprintf("exit %d", fake.Status) +} + +func (fake FakeExitError) Error() string { + return fake.String() +} + +// Exited always returns true +func (fake FakeExitError) Exited() bool { + return true +} + +// ExitStatus returns the fake status +func (fake FakeExitError) ExitStatus() int { + return fake.Status +} diff --git a/vendor/k8s.io/utils/field/path.go b/vendor/k8s.io/utils/field/path.go new file mode 100644 index 0000000000..2efc8eec76 --- /dev/null +++ b/vendor/k8s.io/utils/field/path.go @@ -0,0 +1,91 @@ +/* +Copyright 2015 The Kubernetes 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. +*/ + +package field + +import ( + "bytes" + "fmt" + "strconv" +) + +// Path represents the path from some root to a particular field. +type Path struct { + name string // the name of this field or "" if this is an index + index string // if name == "", this is a subscript (index or map key) of the previous element + parent *Path // nil if this is the root element +} + +// NewPath creates a root Path object. +func NewPath(name string, moreNames ...string) *Path { + r := &Path{name: name, parent: nil} + for _, anotherName := range moreNames { + r = &Path{name: anotherName, parent: r} + } + return r +} + +// Root returns the root element of this Path. +func (p *Path) Root() *Path { + for ; p.parent != nil; p = p.parent { + // Do nothing. + } + return p +} + +// Child creates a new Path that is a child of the method receiver. +func (p *Path) Child(name string, moreNames ...string) *Path { + r := NewPath(name, moreNames...) + r.Root().parent = p + return r +} + +// Index indicates that the previous Path is to be subscripted by an int. +// This sets the same underlying value as Key. +func (p *Path) Index(index int) *Path { + return &Path{index: strconv.Itoa(index), parent: p} +} + +// Key indicates that the previous Path is to be subscripted by a string. +// This sets the same underlying value as Index. +func (p *Path) Key(key string) *Path { + return &Path{index: key, parent: p} +} + +// String produces a string representation of the Path. +func (p *Path) String() string { + // make a slice to iterate + elems := []*Path{} + for ; p != nil; p = p.parent { + elems = append(elems, p) + } + + // iterate, but it has to be backwards + buf := bytes.NewBuffer(nil) + for i := range elems { + p := elems[len(elems)-1-i] + if p.parent != nil && len(p.name) > 0 { + // This is either the root or it is a subscript. + buf.WriteString(".") + } + if len(p.name) > 0 { + buf.WriteString(p.name) + } else { + fmt.Fprintf(buf, "[%s]", p.index) + } + } + return buf.String() +} diff --git a/vendor/k8s.io/utils/inotify/LICENSE b/vendor/k8s.io/utils/inotify/LICENSE new file mode 100644 index 0000000000..6a66aea5ea --- /dev/null +++ b/vendor/k8s.io/utils/inotify/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/k8s.io/utils/inotify/PATENTS b/vendor/k8s.io/utils/inotify/PATENTS new file mode 100644 index 0000000000..733099041f --- /dev/null +++ b/vendor/k8s.io/utils/inotify/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the Go project. + +Google 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, +transfer and otherwise run, modify and propagate the contents of this +implementation of Go, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of Go. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of Go or any code incorporated within this +implementation of Go constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of Go +shall terminate as of the date such litigation is filed. diff --git a/vendor/k8s.io/utils/inotify/inotify_linux.go b/vendor/k8s.io/utils/inotify/inotify_linux.go new file mode 100644 index 0000000000..04d0652b45 --- /dev/null +++ b/vendor/k8s.io/utils/inotify/inotify_linux.go @@ -0,0 +1,333 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +/* +Package inotify implements a wrapper for the Linux inotify system. + +Example: + watcher, err := inotify.NewWatcher() + if err != nil { + log.Fatal(err) + } + err = watcher.Watch("/tmp") + if err != nil { + log.Fatal(err) + } + for { + select { + case ev := <-watcher.Event: + log.Println("event:", ev) + case err := <-watcher.Error: + log.Println("error:", err) + } + } + +*/ +package inotify // import "k8s.io/utils/inotify" + +import ( + "errors" + "fmt" + "os" + "strings" + "sync" + "syscall" + "unsafe" +) + +// Event represents a notification +type Event struct { + Mask uint32 // Mask of events + Cookie uint32 // Unique cookie associating related events (for rename(2)) + Name string // File name (optional) +} + +type watch struct { + wd uint32 // Watch descriptor (as returned by the inotify_add_watch() syscall) + flags uint32 // inotify flags of this watch (see inotify(7) for the list of valid flags) +} + +// Watcher represents an inotify instance +type Watcher struct { + mu sync.Mutex + fd int // File descriptor (as returned by the inotify_init() syscall) + watches map[string]*watch // Map of inotify watches (key: path) + paths map[int]string // Map of watched paths (key: watch descriptor) + Error chan error // Errors are sent on this channel + Event chan *Event // Events are returned on this channel + done chan bool // Channel for sending a "quit message" to the reader goroutine + isClosed bool // Set to true when Close() is first called +} + +// NewWatcher creates and returns a new inotify instance using inotify_init(2) +func NewWatcher() (*Watcher, error) { + fd, errno := syscall.InotifyInit1(syscall.IN_CLOEXEC) + if fd == -1 { + return nil, os.NewSyscallError("inotify_init", errno) + } + w := &Watcher{ + fd: fd, + watches: make(map[string]*watch), + paths: make(map[int]string), + Event: make(chan *Event), + Error: make(chan error), + done: make(chan bool, 1), + } + + go w.readEvents() + return w, nil +} + +// Close closes an inotify watcher instance +// It sends a message to the reader goroutine to quit and removes all watches +// associated with the inotify instance +func (w *Watcher) Close() error { + if w.isClosed { + return nil + } + w.isClosed = true + + // Send "quit" message to the reader goroutine + w.done <- true + for path := range w.watches { + w.RemoveWatch(path) + } + + return nil +} + +// AddWatch adds path to the watched file set. +// The flags are interpreted as described in inotify_add_watch(2). +func (w *Watcher) AddWatch(path string, flags uint32) error { + if w.isClosed { + return errors.New("inotify instance already closed") + } + + watchEntry, found := w.watches[path] + if found { + watchEntry.flags |= flags + flags |= syscall.IN_MASK_ADD + } + + w.mu.Lock() // synchronize with readEvents goroutine + + wd, err := syscall.InotifyAddWatch(w.fd, path, flags) + if err != nil { + w.mu.Unlock() + return &os.PathError{ + Op: "inotify_add_watch", + Path: path, + Err: err, + } + } + + if !found { + w.watches[path] = &watch{wd: uint32(wd), flags: flags} + w.paths[wd] = path + } + w.mu.Unlock() + return nil +} + +// Watch adds path to the watched file set, watching all events. +func (w *Watcher) Watch(path string) error { + return w.AddWatch(path, InAllEvents) +} + +// RemoveWatch removes path from the watched file set. +func (w *Watcher) RemoveWatch(path string) error { + watch, ok := w.watches[path] + if !ok { + return fmt.Errorf("can't remove non-existent inotify watch for: %s", path) + } + success, errno := syscall.InotifyRmWatch(w.fd, watch.wd) + if success == -1 { + return os.NewSyscallError("inotify_rm_watch", errno) + } + delete(w.watches, path) + // Locking here to protect the read from paths in readEvents. + w.mu.Lock() + delete(w.paths, int(watch.wd)) + w.mu.Unlock() + return nil +} + +// readEvents reads from the inotify file descriptor, converts the +// received events into Event objects and sends them via the Event channel +func (w *Watcher) readEvents() { + var buf [syscall.SizeofInotifyEvent * 4096]byte + + for { + n, err := syscall.Read(w.fd, buf[:]) + // See if there is a message on the "done" channel + var done bool + select { + case done = <-w.done: + default: + } + + // If EOF or a "done" message is received + if n == 0 || done { + // The syscall.Close can be slow. Close + // w.Event first. + close(w.Event) + err := syscall.Close(w.fd) + if err != nil { + w.Error <- os.NewSyscallError("close", err) + } + close(w.Error) + return + } + if n < 0 { + w.Error <- os.NewSyscallError("read", err) + continue + } + if n < syscall.SizeofInotifyEvent { + w.Error <- errors.New("inotify: short read in readEvents()") + continue + } + + var offset uint32 + // We don't know how many events we just read into the buffer + // While the offset points to at least one whole event... + for offset <= uint32(n-syscall.SizeofInotifyEvent) { + // Point "raw" to the event in the buffer + raw := (*syscall.InotifyEvent)(unsafe.Pointer(&buf[offset])) + event := new(Event) + event.Mask = uint32(raw.Mask) + event.Cookie = uint32(raw.Cookie) + nameLen := uint32(raw.Len) + // If the event happened to the watched directory or the watched file, the kernel + // doesn't append the filename to the event, but we would like to always fill the + // the "Name" field with a valid filename. We retrieve the path of the watch from + // the "paths" map. + w.mu.Lock() + name, ok := w.paths[int(raw.Wd)] + w.mu.Unlock() + if ok { + event.Name = name + if nameLen > 0 { + // Point "bytes" at the first byte of the filename + bytes := (*[syscall.PathMax]byte)(unsafe.Pointer(&buf[offset+syscall.SizeofInotifyEvent])) + // The filename is padded with NUL bytes. TrimRight() gets rid of those. + event.Name += "/" + strings.TrimRight(string(bytes[0:nameLen]), "\000") + } + // Send the event on the events channel + w.Event <- event + } + // Move to the next event in the buffer + offset += syscall.SizeofInotifyEvent + nameLen + } + } +} + +// String formats the event e in the form +// "filename: 0xEventMask = IN_ACCESS|IN_ATTRIB_|..." +func (e *Event) String() string { + var events string + + m := e.Mask + for _, b := range eventBits { + if m&b.Value == b.Value { + m &^= b.Value + events += "|" + b.Name + } + } + + if m != 0 { + events += fmt.Sprintf("|%#x", m) + } + if len(events) > 0 { + events = " == " + events[1:] + } + + return fmt.Sprintf("%q: %#x%s", e.Name, e.Mask, events) +} + +const ( + // Options for inotify_init() are not exported + // IN_CLOEXEC uint32 = syscall.IN_CLOEXEC + // IN_NONBLOCK uint32 = syscall.IN_NONBLOCK + + // Options for AddWatch + + // InDontFollow : Don't dereference pathname if it is a symbolic link + InDontFollow uint32 = syscall.IN_DONT_FOLLOW + // InOneshot : Monitor the filesystem object corresponding to pathname for one event, then remove from watch list + InOneshot uint32 = syscall.IN_ONESHOT + // InOnlydir : Watch pathname only if it is a directory + InOnlydir uint32 = syscall.IN_ONLYDIR + + // The "IN_MASK_ADD" option is not exported, as AddWatch + // adds it automatically, if there is already a watch for the given path + // IN_MASK_ADD uint32 = syscall.IN_MASK_ADD + + // Events + + // InAccess : File was accessed + InAccess uint32 = syscall.IN_ACCESS + // InAllEvents : Bit mask for all notify events + InAllEvents uint32 = syscall.IN_ALL_EVENTS + // InAttrib : Metadata changed + InAttrib uint32 = syscall.IN_ATTRIB + // InClose : Equates to IN_CLOSE_WRITE | IN_CLOSE_NOWRITE + InClose uint32 = syscall.IN_CLOSE + // InCloseNowrite : File or directory not opened for writing was closed + InCloseNowrite uint32 = syscall.IN_CLOSE_NOWRITE + // InCloseWrite : File opened for writing was closed + InCloseWrite uint32 = syscall.IN_CLOSE_WRITE + // InCreate : File/directory created in watched directory + InCreate uint32 = syscall.IN_CREATE + // InDelete : File/directory deleted from watched directory + InDelete uint32 = syscall.IN_DELETE + // InDeleteSelf : Watched file/directory was itself deleted + InDeleteSelf uint32 = syscall.IN_DELETE_SELF + // InModify : File was modified + InModify uint32 = syscall.IN_MODIFY + // InMove : Equates to IN_MOVED_FROM | IN_MOVED_TO + InMove uint32 = syscall.IN_MOVE + // InMovedFrom : Generated for the directory containing the old filename when a file is renamed + InMovedFrom uint32 = syscall.IN_MOVED_FROM + // InMovedTo : Generated for the directory containing the new filename when a file is renamed + InMovedTo uint32 = syscall.IN_MOVED_TO + // InMoveSelf : Watched file/directory was itself moved + InMoveSelf uint32 = syscall.IN_MOVE_SELF + // InOpen : File or directory was opened + InOpen uint32 = syscall.IN_OPEN + + // Special events + + // InIsdir : Subject of this event is a directory + InIsdir uint32 = syscall.IN_ISDIR + // InIgnored : Watch was removed explicitly or automatically + InIgnored uint32 = syscall.IN_IGNORED + // InQOverflow : Event queue overflowed + InQOverflow uint32 = syscall.IN_Q_OVERFLOW + // InUnmount : Filesystem containing watched object was unmounted + InUnmount uint32 = syscall.IN_UNMOUNT +) + +var eventBits = []struct { + Value uint32 + Name string +}{ + {InAccess, "IN_ACCESS"}, + {InAttrib, "IN_ATTRIB"}, + {InClose, "IN_CLOSE"}, + {InCloseNowrite, "IN_CLOSE_NOWRITE"}, + {InCloseWrite, "IN_CLOSE_WRITE"}, + {InCreate, "IN_CREATE"}, + {InDelete, "IN_DELETE"}, + {InDeleteSelf, "IN_DELETE_SELF"}, + {InModify, "IN_MODIFY"}, + {InMove, "IN_MOVE"}, + {InMovedFrom, "IN_MOVED_FROM"}, + {InMovedTo, "IN_MOVED_TO"}, + {InMoveSelf, "IN_MOVE_SELF"}, + {InOpen, "IN_OPEN"}, + {InIsdir, "IN_ISDIR"}, + {InIgnored, "IN_IGNORED"}, + {InQOverflow, "IN_Q_OVERFLOW"}, + {InUnmount, "IN_UNMOUNT"}, +} diff --git a/vendor/k8s.io/utils/integer/integer.go b/vendor/k8s.io/utils/integer/integer.go new file mode 100644 index 0000000000..e4e740cad4 --- /dev/null +++ b/vendor/k8s.io/utils/integer/integer.go @@ -0,0 +1,73 @@ +/* +Copyright 2016 The Kubernetes 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. +*/ + +package integer + +// IntMax returns the maximum of the params +func IntMax(a, b int) int { + if b > a { + return b + } + return a +} + +// IntMin returns the minimum of the params +func IntMin(a, b int) int { + if b < a { + return b + } + return a +} + +// Int32Max returns the maximum of the params +func Int32Max(a, b int32) int32 { + if b > a { + return b + } + return a +} + +// Int32Min returns the minimum of the params +func Int32Min(a, b int32) int32 { + if b < a { + return b + } + return a +} + +// Int64Max returns the maximum of the params +func Int64Max(a, b int64) int64 { + if b > a { + return b + } + return a +} + +// Int64Min returns the minimum of the params +func Int64Min(a, b int64) int64 { + if b < a { + return b + } + return a +} + +// RoundToInt32 rounds floats into integer numbers. +func RoundToInt32(a float64) int32 { + if a < 0 { + return int32(a - 0.5) + } + return int32(a + 0.5) +} diff --git a/vendor/k8s.io/utils/io/read.go b/vendor/k8s.io/utils/io/read.go new file mode 100644 index 0000000000..16a638d764 --- /dev/null +++ b/vendor/k8s.io/utils/io/read.go @@ -0,0 +1,74 @@ +/* +Copyright 2017 The Kubernetes 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. +*/ + +package io + +import ( + "bytes" + "errors" + "fmt" + "io" + "io/ioutil" +) + +// ErrLimitReached means that the read limit is reached. +var ErrLimitReached = errors.New("the read limit is reached") + +// ConsistentRead repeatedly reads a file until it gets the same content twice. +// This is useful when reading files in /proc that are larger than page size +// and kernel may modify them between individual read() syscalls. +func ConsistentRead(filename string, attempts int) ([]byte, error) { + return consistentReadSync(filename, attempts, nil) +} + +// consistentReadSync is the main functionality of ConsistentRead but +// introduces a sync callback that can be used by the tests to mutate the file +// from which the test data is being read +func consistentReadSync(filename string, attempts int, sync func(int)) ([]byte, error) { + oldContent, err := ioutil.ReadFile(filename) + if err != nil { + return nil, err + } + for i := 0; i < attempts; i++ { + if sync != nil { + sync(i) + } + newContent, err := ioutil.ReadFile(filename) + if err != nil { + return nil, err + } + if bytes.Compare(oldContent, newContent) == 0 { + return newContent, nil + } + // Files are different, continue reading + oldContent = newContent + } + return nil, fmt.Errorf("could not get consistent content of %s after %d attempts", filename, attempts) +} + +// ReadAtMost reads up to `limit` bytes from `r`, and reports an error +// when `limit` bytes are read. +func ReadAtMost(r io.Reader, limit int64) ([]byte, error) { + limitedReader := &io.LimitedReader{R: r, N: limit} + data, err := ioutil.ReadAll(limitedReader) + if err != nil { + return data, err + } + if limitedReader.N <= 0 { + return data, ErrLimitReached + } + return data, nil +} diff --git a/vendor/k8s.io/utils/keymutex/hashed.go b/vendor/k8s.io/utils/keymutex/hashed.go new file mode 100644 index 0000000000..4ddb00867f --- /dev/null +++ b/vendor/k8s.io/utils/keymutex/hashed.go @@ -0,0 +1,58 @@ +/* +Copyright 2018 The Kubernetes 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. +*/ + +package keymutex + +import ( + "hash/fnv" + "runtime" + "sync" +) + +// NewHashed returns a new instance of KeyMutex which hashes arbitrary keys to +// a fixed set of locks. `n` specifies number of locks, if n <= 0, we use +// number of cpus. +// Note that because it uses fixed set of locks, different keys may share same +// lock, so it's possible to wait on same lock. +func NewHashed(n int) KeyMutex { + if n <= 0 { + n = runtime.NumCPU() + } + return &hashedKeyMutex{ + mutexes: make([]sync.Mutex, n), + } +} + +type hashedKeyMutex struct { + mutexes []sync.Mutex +} + +// Acquires a lock associated with the specified ID. +func (km *hashedKeyMutex) LockKey(id string) { + km.mutexes[km.hash(id)%uint32(len(km.mutexes))].Lock() +} + +// Releases the lock associated with the specified ID. +func (km *hashedKeyMutex) UnlockKey(id string) error { + km.mutexes[km.hash(id)%uint32(len(km.mutexes))].Unlock() + return nil +} + +func (km *hashedKeyMutex) hash(id string) uint32 { + h := fnv.New32a() + h.Write([]byte(id)) + return h.Sum32() +} diff --git a/vendor/k8s.io/utils/keymutex/keymutex.go b/vendor/k8s.io/utils/keymutex/keymutex.go new file mode 100644 index 0000000000..89dc022397 --- /dev/null +++ b/vendor/k8s.io/utils/keymutex/keymutex.go @@ -0,0 +1,27 @@ +/* +Copyright 2015 The Kubernetes 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. +*/ + +package keymutex + +// KeyMutex is a thread-safe interface for acquiring locks on arbitrary strings. +type KeyMutex interface { + // Acquires a lock associated with the specified ID, creates the lock if one doesn't already exist. + LockKey(id string) + + // Releases the lock associated with the specified ID. + // Returns an error if the specified ID doesn't exist. + UnlockKey(id string) error +} diff --git a/vendor/k8s.io/utils/net/ipnet.go b/vendor/k8s.io/utils/net/ipnet.go new file mode 100644 index 0000000000..abbb37a546 --- /dev/null +++ b/vendor/k8s.io/utils/net/ipnet.go @@ -0,0 +1,121 @@ +/* +Copyright 2016 The Kubernetes 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. +*/ + +package net + +import ( + "net" + "strings" +) + +// IPNetSet maps string to net.IPNet. +type IPNetSet map[string]*net.IPNet + +// ParseIPNets parses string slice to IPNetSet. +func ParseIPNets(specs ...string) (IPNetSet, error) { + ipnetset := make(IPNetSet) + for _, spec := range specs { + spec = strings.TrimSpace(spec) + _, ipnet, err := net.ParseCIDR(spec) + if err != nil { + return nil, err + } + k := ipnet.String() // In case of normalization + ipnetset[k] = ipnet + } + return ipnetset, nil +} + +// Insert adds items to the set. +func (s IPNetSet) Insert(items ...*net.IPNet) { + for _, item := range items { + s[item.String()] = item + } +} + +// Delete removes all items from the set. +func (s IPNetSet) Delete(items ...*net.IPNet) { + for _, item := range items { + delete(s, item.String()) + } +} + +// Has returns true if and only if item is contained in the set. +func (s IPNetSet) Has(item *net.IPNet) bool { + _, contained := s[item.String()] + return contained +} + +// HasAll returns true if and only if all items are contained in the set. +func (s IPNetSet) HasAll(items ...*net.IPNet) bool { + for _, item := range items { + if !s.Has(item) { + return false + } + } + return true +} + +// Difference returns a set of objects that are not in s2 +// For example: +// s1 = {a1, a2, a3} +// s2 = {a1, a2, a4, a5} +// s1.Difference(s2) = {a3} +// s2.Difference(s1) = {a4, a5} +func (s IPNetSet) Difference(s2 IPNetSet) IPNetSet { + result := make(IPNetSet) + for k, i := range s { + _, found := s2[k] + if found { + continue + } + result[k] = i + } + return result +} + +// StringSlice returns a []string with the String representation of each element in the set. +// Order is undefined. +func (s IPNetSet) StringSlice() []string { + a := make([]string, 0, len(s)) + for k := range s { + a = append(a, k) + } + return a +} + +// IsSuperset returns true if and only if s1 is a superset of s2. +func (s IPNetSet) IsSuperset(s2 IPNetSet) bool { + for k := range s2 { + _, found := s[k] + if !found { + return false + } + } + return true +} + +// Equal returns true if and only if s1 is equal (as a set) to s2. +// Two sets are equal if their membership is identical. +// (In practice, this means same elements, order doesn't matter) +func (s IPNetSet) Equal(s2 IPNetSet) bool { + return len(s) == len(s2) && s.IsSuperset(s2) +} + +// Len returns the size of the set. +func (s IPNetSet) Len() int { + return len(s) +} diff --git a/vendor/k8s.io/utils/net/net.go b/vendor/k8s.io/utils/net/net.go new file mode 100644 index 0000000000..760488f0ea --- /dev/null +++ b/vendor/k8s.io/utils/net/net.go @@ -0,0 +1,148 @@ +/* +Copyright 2018 The Kubernetes 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. +*/ + +package net + +import ( + "fmt" + "net" + "strconv" +) + +// ParseCIDRs parses a list of cidrs and return error if any is invalid. +// order is maintained +func ParseCIDRs(cidrsString []string) ([]*net.IPNet, error) { + cidrs := make([]*net.IPNet, 0, len(cidrsString)) + for _, cidrString := range cidrsString { + _, cidr, err := net.ParseCIDR(cidrString) + if err != nil { + return nil, fmt.Errorf("failed to parse cidr value:%q with error:%v", cidrString, err) + } + cidrs = append(cidrs, cidr) + } + return cidrs, nil +} + +// IsDualStackIPs returns if a slice of ips is: +// - all are valid ips +// - at least one ip from each family (v4 or v6) +func IsDualStackIPs(ips []net.IP) (bool, error) { + v4Found := false + v6Found := false + for _, ip := range ips { + if ip == nil { + return false, fmt.Errorf("ip %v is invalid", ip) + } + + if v4Found && v6Found { + continue + } + + if IsIPv6(ip) { + v6Found = true + continue + } + + v4Found = true + } + + return (v4Found && v6Found), nil +} + +// IsDualStackIPStrings returns if +// - all are valid ips +// - at least one ip from each family (v4 or v6) +func IsDualStackIPStrings(ips []string) (bool, error) { + parsedIPs := make([]net.IP, 0, len(ips)) + for _, ip := range ips { + parsedIP := net.ParseIP(ip) + parsedIPs = append(parsedIPs, parsedIP) + } + return IsDualStackIPs(parsedIPs) +} + +// IsDualStackCIDRs returns if +// - all are valid cidrs +// - at least one cidr from each family (v4 or v6) +func IsDualStackCIDRs(cidrs []*net.IPNet) (bool, error) { + v4Found := false + v6Found := false + for _, cidr := range cidrs { + if cidr == nil { + return false, fmt.Errorf("cidr %v is invalid", cidr) + } + + if v4Found && v6Found { + continue + } + + if IsIPv6(cidr.IP) { + v6Found = true + continue + } + v4Found = true + } + + return v4Found && v6Found, nil +} + +// IsDualStackCIDRStrings returns if +// - all are valid cidrs +// - at least one cidr from each family (v4 or v6) +func IsDualStackCIDRStrings(cidrs []string) (bool, error) { + parsedCIDRs, err := ParseCIDRs(cidrs) + if err != nil { + return false, err + } + return IsDualStackCIDRs(parsedCIDRs) +} + +// IsIPv6 returns if netIP is IPv6. +func IsIPv6(netIP net.IP) bool { + return netIP != nil && netIP.To4() == nil +} + +// IsIPv6String returns if ip is IPv6. +func IsIPv6String(ip string) bool { + netIP := net.ParseIP(ip) + return IsIPv6(netIP) +} + +// IsIPv6CIDRString returns if cidr is IPv6. +// This assumes cidr is a valid CIDR. +func IsIPv6CIDRString(cidr string) bool { + ip, _, _ := net.ParseCIDR(cidr) + return IsIPv6(ip) +} + +// IsIPv6CIDR returns if a cidr is ipv6 +func IsIPv6CIDR(cidr *net.IPNet) bool { + ip := cidr.IP + return IsIPv6(ip) +} + +// ParsePort parses a string representing an IP port. If the string is not a +// valid port number, this returns an error. +func ParsePort(port string) (int, error) { + portInt, err := strconv.Atoi(port) + if err != nil { + return 0, err + } + if !(0 < portInt && portInt <= 65535) { + return 0, fmt.Errorf("%d is not a valid port: must be between 1 and 65535, inclusive", portInt) + } + return portInt, nil +} diff --git a/vendor/k8s.io/utils/nsenter/nsenter.go b/vendor/k8s.io/utils/nsenter/nsenter.go new file mode 100644 index 0000000000..a6fa0c2237 --- /dev/null +++ b/vendor/k8s.io/utils/nsenter/nsenter.go @@ -0,0 +1,258 @@ +// +build linux + +/* +Copyright 2017 The Kubernetes 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. +*/ + +package nsenter + +import ( + "context" + "errors" + "fmt" + "os" + "path/filepath" + "strings" + + "k8s.io/klog" + "k8s.io/utils/exec" +) + +const ( + // DefaultHostRootFsPath is path to host's filesystem mounted into container + // with kubelet. + DefaultHostRootFsPath = "/rootfs" + // mountNsPath is the default mount namespace of the host + mountNsPath = "/proc/1/ns/mnt" + // nsenterPath is the default nsenter command + nsenterPath = "nsenter" +) + +// Nsenter is a type alias for backward compatibility +type Nsenter = NSEnter + +// NSEnter is part of experimental support for running the kubelet +// in a container. +// +// NSEnter requires: +// +// 1. Docker >= 1.6 due to the dependency on the slave propagation mode +// of the bind-mount of the kubelet root directory in the container. +// Docker 1.5 used a private propagation mode for bind-mounts, so mounts +// performed in the host's mount namespace do not propagate out to the +// bind-mount in this docker version. +// 2. The host's root filesystem must be available at /rootfs +// 3. The nsenter binary must be on the Kubelet process' PATH in the container's +// filesystem. +// 4. The Kubelet process must have CAP_SYS_ADMIN (required by nsenter); at +// the present, this effectively means that the kubelet is running in a +// privileged container. +// 5. The volume path used by the Kubelet must be the same inside and outside +// the container and be writable by the container (to initialize volume) +// contents. TODO: remove this requirement. +// 6. The host image must have "mount", "findmnt", "umount", "stat", "touch", +// "mkdir", "ls", "sh" and "chmod" binaries in /bin, /usr/sbin, or /usr/bin +// 7. The host image should have systemd-run in /bin, /usr/sbin, or /usr/bin if +// systemd is installed/enabled in the operating system. +// For more information about mount propagation modes, see: +// https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt +type NSEnter struct { + // a map of commands to their paths on the host filesystem + paths map[string]string + + // Path to the host filesystem, typically "/rootfs". Used only for testing. + hostRootFsPath string + + // Exec implementation + executor exec.Interface +} + +// NewNsenter constructs a new instance of NSEnter +func NewNsenter(hostRootFsPath string, executor exec.Interface) (*NSEnter, error) { + ne := &NSEnter{ + hostRootFsPath: hostRootFsPath, + executor: executor, + } + if err := ne.initPaths(); err != nil { + return nil, err + } + return ne, nil +} + +func (ne *NSEnter) initPaths() error { + ne.paths = map[string]string{} + binaries := []string{ + "mount", + "findmnt", + "umount", + "systemd-run", + "stat", + "touch", + "mkdir", + "sh", + "chmod", + "realpath", + } + // search for the required commands in other locations besides /usr/bin + for _, binary := range binaries { + // check for binary under the following directories + for _, path := range []string{"/", "/bin", "/usr/sbin", "/usr/bin"} { + binPath := filepath.Join(path, binary) + if _, err := os.Stat(filepath.Join(ne.hostRootFsPath, binPath)); err != nil { + continue + } + ne.paths[binary] = binPath + break + } + // systemd-run is optional, bailout if we don't find any of the other binaries + if ne.paths[binary] == "" && binary != "systemd-run" { + return fmt.Errorf("unable to find %v", binary) + } + } + return nil +} + +// Exec executes nsenter commands in hostProcMountNsPath mount namespace +func (ne *NSEnter) Exec(cmd string, args []string) exec.Cmd { + hostProcMountNsPath := filepath.Join(ne.hostRootFsPath, mountNsPath) + fullArgs := append([]string{fmt.Sprintf("--mount=%s", hostProcMountNsPath), "--"}, + append([]string{ne.AbsHostPath(cmd)}, args...)...) + klog.V(5).Infof("Running nsenter command: %v %v", nsenterPath, fullArgs) + return ne.executor.Command(nsenterPath, fullArgs...) +} + +// Command returns a command wrapped with nsenter +func (ne *NSEnter) Command(cmd string, args ...string) exec.Cmd { + return ne.Exec(cmd, args) +} + +// CommandContext returns a CommandContext wrapped with nsenter +func (ne *NSEnter) CommandContext(ctx context.Context, cmd string, args ...string) exec.Cmd { + hostProcMountNsPath := filepath.Join(ne.hostRootFsPath, mountNsPath) + fullArgs := append([]string{fmt.Sprintf("--mount=%s", hostProcMountNsPath), "--"}, + append([]string{ne.AbsHostPath(cmd)}, args...)...) + klog.V(5).Infof("Running nsenter command: %v %v", nsenterPath, fullArgs) + return ne.executor.CommandContext(ctx, nsenterPath, fullArgs...) +} + +// LookPath returns a LookPath wrapped with nsenter +func (ne *NSEnter) LookPath(file string) (string, error) { + return "", fmt.Errorf("not implemented, error looking up : %s", file) +} + +// AbsHostPath returns the absolute runnable path for a specified command +func (ne *NSEnter) AbsHostPath(command string) string { + path, ok := ne.paths[command] + if !ok { + return command + } + return path +} + +// SupportsSystemd checks whether command systemd-run exists +func (ne *NSEnter) SupportsSystemd() (string, bool) { + systemdRunPath, ok := ne.paths["systemd-run"] + return systemdRunPath, ok && systemdRunPath != "" +} + +// EvalSymlinks returns the path name on the host after evaluating symlinks on the +// host. +// mustExist makes EvalSymlinks to return error when the path does not +// exist. When it's false, it evaluates symlinks of the existing part and +// blindly adds the non-existing part: +// pathname: /mnt/volume/non/existing/directory +// /mnt/volume exists +// non/existing/directory does not exist +// -> It resolves symlinks in /mnt/volume to say /mnt/foo and returns +// /mnt/foo/non/existing/directory. +// +// BEWARE! EvalSymlinks is not able to detect symlink looks with mustExist=false! +// If /tmp/link is symlink to /tmp/link, EvalSymlinks(/tmp/link/foo) returns /tmp/link/foo. +func (ne *NSEnter) EvalSymlinks(pathname string, mustExist bool) (string, error) { + var args []string + if mustExist { + // "realpath -e: all components of the path must exist" + args = []string{"-e", pathname} + } else { + // "realpath -m: no path components need exist or be a directory" + args = []string{"-m", pathname} + } + outBytes, err := ne.Exec("realpath", args).CombinedOutput() + if err != nil { + klog.Infof("failed to resolve symbolic links on %s: %v", pathname, err) + return "", err + } + return strings.TrimSpace(string(outBytes)), nil +} + +// KubeletPath returns the path name that can be accessed by containerized +// kubelet. It is recommended to resolve symlinks on the host by EvalSymlinks +// before calling this function +func (ne *NSEnter) KubeletPath(pathname string) string { + return filepath.Join(ne.hostRootFsPath, pathname) +} + +// NewFakeNsenter returns a NSEnter that does not run "nsenter --mount=... --", +// but runs everything in the same mount namespace as the unit test binary. +// rootfsPath is supposed to be a symlink, e.g. /tmp/xyz/rootfs -> /. +// This fake NSEnter is enough for most operations, e.g. to resolve symlinks, +// but it's not enough to call /bin/mount - unit tests don't run as root. +func NewFakeNsenter(rootfsPath string) (*NSEnter, error) { + executor := &fakeExec{ + rootfsPath: rootfsPath, + } + // prepare /rootfs/bin, usr/bin and usr/sbin + bin := filepath.Join(rootfsPath, "bin") + if err := os.Symlink("/bin", bin); err != nil { + return nil, err + } + + usr := filepath.Join(rootfsPath, "usr") + if err := os.Mkdir(usr, 0755); err != nil { + return nil, err + } + usrbin := filepath.Join(usr, "bin") + if err := os.Symlink("/usr/bin", usrbin); err != nil { + return nil, err + } + usrsbin := filepath.Join(usr, "sbin") + if err := os.Symlink("/usr/sbin", usrsbin); err != nil { + return nil, err + } + + return NewNsenter(rootfsPath, executor) +} + +type fakeExec struct { + rootfsPath string +} + +func (f fakeExec) Command(cmd string, args ...string) exec.Cmd { + // This will intentionaly panic if NSEnter does not provide enough arguments. + realCmd := args[2] + realArgs := args[3:] + return exec.New().Command(realCmd, realArgs...) +} + +func (fakeExec) LookPath(file string) (string, error) { + return "", errors.New("not implemented") +} + +func (fakeExec) CommandContext(ctx context.Context, cmd string, args ...string) exec.Cmd { + return nil +} + +var _ exec.Interface = fakeExec{} +var _ exec.Interface = &NSEnter{} diff --git a/vendor/k8s.io/utils/nsenter/nsenter_unsupported.go b/vendor/k8s.io/utils/nsenter/nsenter_unsupported.go new file mode 100644 index 0000000000..e38c7e8113 --- /dev/null +++ b/vendor/k8s.io/utils/nsenter/nsenter_unsupported.go @@ -0,0 +1,79 @@ +// +build !linux + +/* +Copyright 2017 The Kubernetes 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. +*/ + +package nsenter + +import ( + "context" + "fmt" + + "k8s.io/utils/exec" +) + +const ( + // DefaultHostRootFsPath is path to host's filesystem mounted into container + // with kubelet. + DefaultHostRootFsPath = "/rootfs" +) + +// Nsenter is a type alias for backward compatibility +type Nsenter = NSEnter + +// NSEnter is part of experimental support for running the kubelet +// in a container. +type NSEnter struct { + // a map of commands to their paths on the host filesystem + Paths map[string]string +} + +// NewNsenter constructs a new instance of NSEnter +func NewNsenter(hostRootFsPath string, executor exec.Interface) (*Nsenter, error) { + return &Nsenter{}, nil +} + +// Exec executes nsenter commands in hostProcMountNsPath mount namespace +func (ne *NSEnter) Exec(cmd string, args []string) exec.Cmd { + return nil +} + +// AbsHostPath returns the absolute runnable path for a specified command +func (ne *NSEnter) AbsHostPath(command string) string { + return "" +} + +// SupportsSystemd checks whether command systemd-run exists +func (ne *NSEnter) SupportsSystemd() (string, bool) { + return "", false +} + +// Command returns a command wrapped with nenter +func (ne *NSEnter) Command(cmd string, args ...string) exec.Cmd { + return nil +} + +// CommandContext returns a CommandContext wrapped with nsenter +func (ne *NSEnter) CommandContext(ctx context.Context, cmd string, args ...string) exec.Cmd { + return nil +} + +// LookPath returns a LookPath wrapped with nsenter +func (ne *NSEnter) LookPath(file string) (string, error) { + return "", fmt.Errorf("not implemented, error looking up : %s", file) +} + +var _ exec.Interface = &NSEnter{} diff --git a/vendor/k8s.io/utils/path/file.go b/vendor/k8s.io/utils/path/file.go new file mode 100644 index 0000000000..a57285d3b4 --- /dev/null +++ b/vendor/k8s.io/utils/path/file.go @@ -0,0 +1,78 @@ +/* +Copyright 2017 The Kubernetes 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. +*/ + +package path + +import ( + "errors" + "os" +) + +// LinkTreatment is the base type for constants used by Exists that indicate +// how symlinks are treated for existence checks. +type LinkTreatment int + +const ( + // CheckFollowSymlink follows the symlink and verifies that the target of + // the symlink exists. + CheckFollowSymlink LinkTreatment = iota + + // CheckSymlinkOnly does not follow the symlink and verfies only that they + // symlink itself exists. + CheckSymlinkOnly +) + +// ErrInvalidLinkTreatment indicates that the link treatment behavior requested +// is not a valid behavior. +var ErrInvalidLinkTreatment = errors.New("unknown link behavior") + +// Exists checks if specified file, directory, or symlink exists. The behavior +// of the test depends on the linkBehaviour argument. See LinkTreatment for +// more details. +func Exists(linkBehavior LinkTreatment, filename string) (bool, error) { + var err error + + if linkBehavior == CheckFollowSymlink { + _, err = os.Stat(filename) + } else if linkBehavior == CheckSymlinkOnly { + _, err = os.Lstat(filename) + } else { + return false, ErrInvalidLinkTreatment + } + + if os.IsNotExist(err) { + return false, nil + } else if err != nil { + return false, err + } + return true, nil +} + +// ReadDirNoStat returns a string of files/directories contained +// in dirname without calling lstat on them. +func ReadDirNoStat(dirname string) ([]string, error) { + if dirname == "" { + dirname = "." + } + + f, err := os.Open(dirname) + if err != nil { + return nil, err + } + defer f.Close() + + return f.Readdirnames(-1) +} diff --git a/vendor/k8s.io/utils/pointer/pointer.go b/vendor/k8s.io/utils/pointer/pointer.go new file mode 100644 index 0000000000..5365a11365 --- /dev/null +++ b/vendor/k8s.io/utils/pointer/pointer.go @@ -0,0 +1,86 @@ +/* +Copyright 2018 The Kubernetes 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. +*/ + +package pointer + +import ( + "fmt" + "reflect" +) + +// AllPtrFieldsNil tests whether all pointer fields in a struct are nil. This is useful when, +// for example, an API struct is handled by plugins which need to distinguish +// "no plugin accepted this spec" from "this spec is empty". +// +// This function is only valid for structs and pointers to structs. Any other +// type will cause a panic. Passing a typed nil pointer will return true. +func AllPtrFieldsNil(obj interface{}) bool { + v := reflect.ValueOf(obj) + if !v.IsValid() { + panic(fmt.Sprintf("reflect.ValueOf() produced a non-valid Value for %#v", obj)) + } + if v.Kind() == reflect.Ptr { + if v.IsNil() { + return true + } + v = v.Elem() + } + for i := 0; i < v.NumField(); i++ { + if v.Field(i).Kind() == reflect.Ptr && !v.Field(i).IsNil() { + return false + } + } + return true +} + +// Int32Ptr returns a pointer to an int32 +func Int32Ptr(i int32) *int32 { + return &i +} + +// Int64Ptr returns a pointer to an int64 +func Int64Ptr(i int64) *int64 { + return &i +} + +// Int32PtrDerefOr dereference the int32 ptr and returns it if not nil, +// else returns def. +func Int32PtrDerefOr(ptr *int32, def int32) int32 { + if ptr != nil { + return *ptr + } + return def +} + +// BoolPtr returns a pointer to a bool +func BoolPtr(b bool) *bool { + return &b +} + +// StringPtr returns a pointer to the passed string. +func StringPtr(s string) *string { + return &s +} + +// Float32Ptr returns a pointer to the passed float32. +func Float32Ptr(i float32) *float32 { + return &i +} + +// Float64Ptr returns a pointer to the passed float64. +func Float64Ptr(i float64) *float64 { + return &i +} diff --git a/vendor/k8s.io/utils/semantic/deep_equal.go b/vendor/k8s.io/utils/semantic/deep_equal.go new file mode 100644 index 0000000000..2f56974c93 --- /dev/null +++ b/vendor/k8s.io/utils/semantic/deep_equal.go @@ -0,0 +1,30 @@ +/* +Copyright 2019 The Kubernetes 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. +*/ + +package semantic + +import ( + "k8s.io/utils/third_party/forked/golang/reflect" +) + +// Equalities is a map from type to a function comparing two values of +// that type. +type Equalities = reflect.Equalities + +// EqualitiesOrDie adds the given funcs and panics on any error. +func EqualitiesOrDie(funcs ...interface{}) Equalities { + return reflect.EqualitiesOrDie(funcs...) +} diff --git a/vendor/k8s.io/utils/strings/escape.go b/vendor/k8s.io/utils/strings/escape.go new file mode 100644 index 0000000000..bae8d81a19 --- /dev/null +++ b/vendor/k8s.io/utils/strings/escape.go @@ -0,0 +1,36 @@ +/* +Copyright 2014 The Kubernetes 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. +*/ + +package strings + +import ( + "strings" +) + +// EscapeQualifiedName converts a plugin name, which might contain a / into a +// string that is safe to use on-disk. This assumes that the input has already +// been validates as a qualified name. we use "~" rather than ":" here in case +// we ever use a filesystem that doesn't allow ":". +func EscapeQualifiedName(in string) string { + return strings.Replace(in, "/", "~", -1) +} + +// UnescapeQualifiedName converts an escaped plugin name (as per EscapeQualifiedName) +// back to its normal form. This assumes that the input has already been +// validates as a qualified name. +func UnescapeQualifiedName(in string) string { + return strings.Replace(in, "~", "/", -1) +} diff --git a/vendor/k8s.io/utils/strings/line_delimiter.go b/vendor/k8s.io/utils/strings/line_delimiter.go new file mode 100644 index 0000000000..8907869c9e --- /dev/null +++ b/vendor/k8s.io/utils/strings/line_delimiter.go @@ -0,0 +1,64 @@ +/* +Copyright 2015 The Kubernetes 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. +*/ + +package strings + +import ( + "bytes" + "io" + "strings" +) + +// LineDelimiter is a filter that will split input on lines +// and bracket each line with the delimiter string. +type LineDelimiter struct { + output io.Writer + delimiter []byte + buf bytes.Buffer +} + +// NewLineDelimiter allocates a new io.Writer that will split input on lines +// and bracket each line with the delimiter string. This can be useful in +// output tests where it is difficult to see and test trailing whitespace. +func NewLineDelimiter(output io.Writer, delimiter string) *LineDelimiter { + return &LineDelimiter{output: output, delimiter: []byte(delimiter)} +} + +// Write writes buf to the LineDelimiter ld. The only errors returned are ones +// encountered while writing to the underlying output stream. +func (ld *LineDelimiter) Write(buf []byte) (n int, err error) { + return ld.buf.Write(buf) +} + +// Flush all lines up until now. This will assume insert a linebreak at the current point of the stream. +func (ld *LineDelimiter) Flush() (err error) { + lines := strings.Split(ld.buf.String(), "\n") + for _, line := range lines { + if _, err = ld.output.Write(ld.delimiter); err != nil { + return + } + if _, err = ld.output.Write([]byte(line)); err != nil { + return + } + if _, err = ld.output.Write(ld.delimiter); err != nil { + return + } + if _, err = ld.output.Write([]byte("\n")); err != nil { + return + } + } + return +} diff --git a/vendor/k8s.io/utils/strings/strings.go b/vendor/k8s.io/utils/strings/strings.go new file mode 100644 index 0000000000..8a9f2eced9 --- /dev/null +++ b/vendor/k8s.io/utils/strings/strings.go @@ -0,0 +1,46 @@ +/* +Copyright 2014 The Kubernetes 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. +*/ + +package strings + +import ( + "path" + "strings" +) + +// SplitQualifiedName Splits a fully qualified name and returns its namespace and name. +// Assumes that the input 'str' has been validated. +func SplitQualifiedName(str string) (string, string) { + parts := strings.Split(str, "/") + if len(parts) < 2 { + return "", str + } + return parts[0], parts[1] +} + +// JoinQualifiedName joins 'namespace' and 'name' and returns a fully qualified name +// Assumes that the input is valid. +func JoinQualifiedName(namespace, name string) string { + return path.Join(namespace, name) +} + +// ShortenString returns the first N slice of a string. +func ShortenString(str string, n int) string { + if len(str) <= n { + return str + } + return str[:n] +} diff --git a/vendor/k8s.io/utils/temp/dir.go b/vendor/k8s.io/utils/temp/dir.go new file mode 100644 index 0000000000..efad69c389 --- /dev/null +++ b/vendor/k8s.io/utils/temp/dir.go @@ -0,0 +1,70 @@ +/* +Copyright 2017 The Kubernetes 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. +*/ + +package temp + +import ( + "fmt" + "io" + "io/ioutil" + "os" + "path/filepath" +) + +// Directory is an interface to a temporary directory, in which you can +// create new files. +type Directory interface { + // NewFile creates a new file in that directory. Calling NewFile + // with the same filename twice will result in an error. + NewFile(name string) (io.WriteCloser, error) + // Delete removes the directory and its content. + Delete() error +} + +// Dir is wrapping an temporary directory on disk. +type Dir struct { + // Name is the name (full path) of the created directory. + Name string +} + +var _ Directory = &Dir{} + +// CreateTempDir returns a new Directory wrapping a temporary directory +// on disk. +func CreateTempDir(prefix string) (*Dir, error) { + name, err := ioutil.TempDir("", fmt.Sprintf("%s-", prefix)) + if err != nil { + return nil, err + } + + return &Dir{ + Name: name, + }, nil +} + +// NewFile creates a new file in the specified directory. +func (d *Dir) NewFile(name string) (io.WriteCloser, error) { + return os.OpenFile( + filepath.Join(d.Name, name), + os.O_WRONLY|os.O_CREATE|os.O_TRUNC|os.O_EXCL, + 0700, + ) +} + +// Delete the underlying directory, and all of its content. +func (d *Dir) Delete() error { + return os.RemoveAll(d.Name) +} diff --git a/vendor/k8s.io/utils/temp/doc.go b/vendor/k8s.io/utils/temp/doc.go new file mode 100644 index 0000000000..b7e0c15ae6 --- /dev/null +++ b/vendor/k8s.io/utils/temp/doc.go @@ -0,0 +1,19 @@ +/* +Copyright 2017 The Kubernetes 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. +*/ + +// Package temp provides an interface to handle temporary files and +// directories. +package temp // import "k8s.io/utils/temp" diff --git a/vendor/k8s.io/utils/temp/temptest/dir.go b/vendor/k8s.io/utils/temp/temptest/dir.go new file mode 100644 index 0000000000..b142765fde --- /dev/null +++ b/vendor/k8s.io/utils/temp/temptest/dir.go @@ -0,0 +1,66 @@ +/* +Copyright 2017 The Kubernetes 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. +*/ + +package temptest + +import ( + "errors" + "fmt" + "io" + + "k8s.io/utils/temp" +) + +// FakeDir implements a Directory that is not backed on the +// filesystem. This is useful for testing since the created "files" are +// simple bytes.Buffer that can be inspected. +type FakeDir struct { + Files map[string]*FakeFile + Deleted bool +} + +var _ temp.Directory = &FakeDir{} + +// NewFile returns a new FakeFile if the filename doesn't exist already. +// This function will fail if the directory has already been deleted. +func (d *FakeDir) NewFile(name string) (io.WriteCloser, error) { + if d.Deleted { + return nil, errors.New("can't create file in deleted FakeDir") + } + if d.Files == nil { + d.Files = map[string]*FakeFile{} + } + f := d.Files[name] + if f != nil { + return nil, fmt.Errorf( + "FakeDir already has file named %q", + name, + ) + } + f = &FakeFile{} + d.Files[name] = f + return f, nil +} + +// Delete doesn't remove anything, but records that the directory has +// been deleted. +func (d *FakeDir) Delete() error { + if d.Deleted { + return errors.New("failed to re-delete FakeDir") + } + d.Deleted = true + return nil +} diff --git a/vendor/k8s.io/utils/temp/temptest/doc.go b/vendor/k8s.io/utils/temp/temptest/doc.go new file mode 100644 index 0000000000..28c4f6a18a --- /dev/null +++ b/vendor/k8s.io/utils/temp/temptest/doc.go @@ -0,0 +1,19 @@ +/* +Copyright 2017 The Kubernetes 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. +*/ + +// Package temptest provides utilities for testing temp +// files/directories testing. +package temptest diff --git a/vendor/k8s.io/utils/temp/temptest/file.go b/vendor/k8s.io/utils/temp/temptest/file.go new file mode 100644 index 0000000000..a6375fb91a --- /dev/null +++ b/vendor/k8s.io/utils/temp/temptest/file.go @@ -0,0 +1,52 @@ +/* +Copyright 2017 The Kubernetes 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. +*/ + +package temptest + +import ( + "bytes" + "errors" + "io" +) + +// FakeFile is an implementation of a WriteCloser, that records what has +// been written in the file (in a bytes.Buffer) and if the file has been +// closed. +type FakeFile struct { + Buffer bytes.Buffer + Closed bool +} + +var _ io.WriteCloser = &FakeFile{} + +// Write appends the contents of p to the Buffer. If the file has +// already been closed, an error is returned. +func (f *FakeFile) Write(p []byte) (n int, err error) { + if f.Closed { + return 0, errors.New("can't write to closed FakeFile") + } + return f.Buffer.Write(p) +} + +// Close records that the file has been closed. If the file has already +// been closed, an error is returned. +func (f *FakeFile) Close() error { + if f.Closed { + return errors.New("FakeFile was closed multiple times") + } + f.Closed = true + return nil +} diff --git a/vendor/k8s.io/utils/third_party/forked/golang/LICENSE b/vendor/k8s.io/utils/third_party/forked/golang/LICENSE new file mode 100644 index 0000000000..7448756763 --- /dev/null +++ b/vendor/k8s.io/utils/third_party/forked/golang/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2012 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/k8s.io/utils/third_party/forked/golang/PATENTS b/vendor/k8s.io/utils/third_party/forked/golang/PATENTS new file mode 100644 index 0000000000..733099041f --- /dev/null +++ b/vendor/k8s.io/utils/third_party/forked/golang/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the Go project. + +Google 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, +transfer and otherwise run, modify and propagate the contents of this +implementation of Go, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of Go. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of Go or any code incorporated within this +implementation of Go constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of Go +shall terminate as of the date such litigation is filed. diff --git a/vendor/k8s.io/utils/third_party/forked/golang/reflect/deep_equal.go b/vendor/k8s.io/utils/third_party/forked/golang/reflect/deep_equal.go new file mode 100644 index 0000000000..2b5a350363 --- /dev/null +++ b/vendor/k8s.io/utils/third_party/forked/golang/reflect/deep_equal.go @@ -0,0 +1,398 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package reflect is a fork of go's standard library reflection package, which +// allows for deep equal with equality functions defined. +package reflect + +import ( + "fmt" + "reflect" + "strings" +) + +// Equalities is a map from type to a function comparing two values of +// that type. +type Equalities map[reflect.Type]reflect.Value + +// EqualitiesOrDie adds the given funcs and panics on any error. +func EqualitiesOrDie(funcs ...interface{}) Equalities { + e := Equalities{} + if err := e.AddFuncs(funcs...); err != nil { + panic(err) + } + return e +} + +// AddFuncs is a shortcut for multiple calls to AddFunc. +func (e Equalities) AddFuncs(funcs ...interface{}) error { + for _, f := range funcs { + if err := e.AddFunc(f); err != nil { + return err + } + } + return nil +} + +// AddFunc uses func as an equality function: it must take +// two parameters of the same type, and return a boolean. +func (e Equalities) AddFunc(eqFunc interface{}) error { + fv := reflect.ValueOf(eqFunc) + ft := fv.Type() + if ft.Kind() != reflect.Func { + return fmt.Errorf("expected func, got: %v", ft) + } + if ft.NumIn() != 2 { + return fmt.Errorf("expected two 'in' params, got: %v", ft) + } + if ft.NumOut() != 1 { + return fmt.Errorf("expected one 'out' param, got: %v", ft) + } + if ft.In(0) != ft.In(1) { + return fmt.Errorf("expected arg 1 and 2 to have same type, but got %v", ft) + } + var forReturnType bool + boolType := reflect.TypeOf(forReturnType) + if ft.Out(0) != boolType { + return fmt.Errorf("expected bool return, got: %v", ft) + } + e[ft.In(0)] = fv + return nil +} + +// Below here is forked from go's reflect/deepequal.go + +// During deepValueEqual, must keep track of checks that are +// in progress. The comparison algorithm assumes that all +// checks in progress are true when it reencounters them. +// Visited comparisons are stored in a map indexed by visit. +type visit struct { + a1 uintptr + a2 uintptr + typ reflect.Type +} + +// unexportedTypePanic is thrown when you use this DeepEqual on something that has an +// unexported type. It indicates a programmer error, so should not occur at runtime, +// which is why it's not public and thus impossible to catch. +type unexportedTypePanic []reflect.Type + +func (u unexportedTypePanic) Error() string { return u.String() } +func (u unexportedTypePanic) String() string { + strs := make([]string, len(u)) + for i, t := range u { + strs[i] = fmt.Sprintf("%v", t) + } + return "an unexported field was encountered, nested like this: " + strings.Join(strs, " -> ") +} + +func makeUsefulPanic(v reflect.Value) { + if x := recover(); x != nil { + if u, ok := x.(unexportedTypePanic); ok { + u = append(unexportedTypePanic{v.Type()}, u...) + x = u + } + panic(x) + } +} + +// deepValueEqual tests for deep equality using reflected types. The map argument tracks +// comparisons that have already been seen, which allows short circuiting on +// recursive types. +func (e Equalities) deepValueEqual(v1, v2 reflect.Value, visited map[visit]bool, depth int) bool { + defer makeUsefulPanic(v1) + + if !v1.IsValid() || !v2.IsValid() { + return v1.IsValid() == v2.IsValid() + } + if v1.Type() != v2.Type() { + return false + } + if fv, ok := e[v1.Type()]; ok { + return fv.Call([]reflect.Value{v1, v2})[0].Bool() + } + if v1.CanAddr() { + if fv, ok := e[v1.Addr().Type()]; ok { + return fv.Call([]reflect.Value{v1.Addr(), v2.Addr()})[0].Bool() + } + } + + hard := func(k reflect.Kind) bool { + switch k { + case reflect.Array, reflect.Map, reflect.Slice, reflect.Struct: + return true + } + return false + } + + if v1.CanAddr() && v2.CanAddr() && hard(v1.Kind()) { + addr1 := v1.UnsafeAddr() + addr2 := v2.UnsafeAddr() + if addr1 > addr2 { + // Canonicalize order to reduce number of entries in visited. + addr1, addr2 = addr2, addr1 + } + + // Short circuit if references are identical ... + if addr1 == addr2 { + return true + } + + // ... or already seen + typ := v1.Type() + v := visit{addr1, addr2, typ} + if visited[v] { + return true + } + + // Remember for later. + visited[v] = true + } + + switch v1.Kind() { + case reflect.Array: + // We don't need to check length here because length is part of + // an array's type, which has already been filtered for. + for i := 0; i < v1.Len(); i++ { + if !e.deepValueEqual(v1.Index(i), v2.Index(i), visited, depth+1) { + return false + } + } + return true + case reflect.Slice: + if (v1.IsNil() || v1.Len() == 0) != (v2.IsNil() || v2.Len() == 0) { + return false + } + if v1.IsNil() || v1.Len() == 0 { + return true + } + if v1.Len() != v2.Len() { + return false + } + if v1.Pointer() == v2.Pointer() { + return true + } + for i := 0; i < v1.Len(); i++ { + if !e.deepValueEqual(v1.Index(i), v2.Index(i), visited, depth+1) { + return false + } + } + return true + case reflect.Interface: + if v1.IsNil() || v2.IsNil() { + return v1.IsNil() == v2.IsNil() + } + return e.deepValueEqual(v1.Elem(), v2.Elem(), visited, depth+1) + case reflect.Ptr: + return e.deepValueEqual(v1.Elem(), v2.Elem(), visited, depth+1) + case reflect.Struct: + for i, n := 0, v1.NumField(); i < n; i++ { + if !e.deepValueEqual(v1.Field(i), v2.Field(i), visited, depth+1) { + return false + } + } + return true + case reflect.Map: + if (v1.IsNil() || v1.Len() == 0) != (v2.IsNil() || v2.Len() == 0) { + return false + } + if v1.IsNil() || v1.Len() == 0 { + return true + } + if v1.Len() != v2.Len() { + return false + } + if v1.Pointer() == v2.Pointer() { + return true + } + for _, k := range v1.MapKeys() { + if !e.deepValueEqual(v1.MapIndex(k), v2.MapIndex(k), visited, depth+1) { + return false + } + } + return true + case reflect.Func: + if v1.IsNil() && v2.IsNil() { + return true + } + // Can't do better than this: + return false + default: + // Normal equality suffices + if !v1.CanInterface() || !v2.CanInterface() { + panic(unexportedTypePanic{}) + } + return v1.Interface() == v2.Interface() + } +} + +// DeepEqual is like reflect.DeepEqual, but focused on semantic equality +// instead of memory equality. +// +// It will use e's equality functions if it finds types that match. +// +// An empty slice *is* equal to a nil slice for our purposes; same for maps. +// +// Unexported field members cannot be compared and will cause an imformative panic; you must add an Equality +// function for these types. +func (e Equalities) DeepEqual(a1, a2 interface{}) bool { + if a1 == nil || a2 == nil { + return a1 == a2 + } + v1 := reflect.ValueOf(a1) + v2 := reflect.ValueOf(a2) + if v1.Type() != v2.Type() { + return false + } + return e.deepValueEqual(v1, v2, make(map[visit]bool), 0) +} + +func (e Equalities) deepValueDerive(v1, v2 reflect.Value, visited map[visit]bool, depth int) bool { + defer makeUsefulPanic(v1) + + if !v1.IsValid() || !v2.IsValid() { + return v1.IsValid() == v2.IsValid() + } + if v1.Type() != v2.Type() { + return false + } + if fv, ok := e[v1.Type()]; ok { + return fv.Call([]reflect.Value{v1, v2})[0].Bool() + } + if v1.CanAddr() { + if fv, ok := e[v1.Addr().Type()]; ok { + return fv.Call([]reflect.Value{v1.Addr(), v2.Addr()})[0].Bool() + } + } + + hard := func(k reflect.Kind) bool { + switch k { + case reflect.Array, reflect.Map, reflect.Slice, reflect.Struct: + return true + } + return false + } + + if v1.CanAddr() && v2.CanAddr() && hard(v1.Kind()) { + addr1 := v1.UnsafeAddr() + addr2 := v2.UnsafeAddr() + if addr1 > addr2 { + // Canonicalize order to reduce number of entries in visited. + addr1, addr2 = addr2, addr1 + } + + // Short circuit if references are identical ... + if addr1 == addr2 { + return true + } + + // ... or already seen + typ := v1.Type() + v := visit{addr1, addr2, typ} + if visited[v] { + return true + } + + // Remember for later. + visited[v] = true + } + + switch v1.Kind() { + case reflect.Array: + // We don't need to check length here because length is part of + // an array's type, which has already been filtered for. + for i := 0; i < v1.Len(); i++ { + if !e.deepValueDerive(v1.Index(i), v2.Index(i), visited, depth+1) { + return false + } + } + return true + case reflect.Slice: + if v1.IsNil() || v1.Len() == 0 { + return true + } + if v1.Len() > v2.Len() { + return false + } + if v1.Pointer() == v2.Pointer() { + return true + } + for i := 0; i < v1.Len(); i++ { + if !e.deepValueDerive(v1.Index(i), v2.Index(i), visited, depth+1) { + return false + } + } + return true + case reflect.String: + if v1.Len() == 0 { + return true + } + if v1.Len() > v2.Len() { + return false + } + return v1.String() == v2.String() + case reflect.Interface: + if v1.IsNil() { + return true + } + return e.deepValueDerive(v1.Elem(), v2.Elem(), visited, depth+1) + case reflect.Ptr: + if v1.IsNil() { + return true + } + return e.deepValueDerive(v1.Elem(), v2.Elem(), visited, depth+1) + case reflect.Struct: + for i, n := 0, v1.NumField(); i < n; i++ { + if !e.deepValueDerive(v1.Field(i), v2.Field(i), visited, depth+1) { + return false + } + } + return true + case reflect.Map: + if v1.IsNil() || v1.Len() == 0 { + return true + } + if v1.Len() > v2.Len() { + return false + } + if v1.Pointer() == v2.Pointer() { + return true + } + for _, k := range v1.MapKeys() { + if !e.deepValueDerive(v1.MapIndex(k), v2.MapIndex(k), visited, depth+1) { + return false + } + } + return true + case reflect.Func: + if v1.IsNil() && v2.IsNil() { + return true + } + // Can't do better than this: + return false + default: + // Normal equality suffices + if !v1.CanInterface() || !v2.CanInterface() { + panic(unexportedTypePanic{}) + } + return v1.Interface() == v2.Interface() + } +} + +// DeepDerivative is similar to DeepEqual except that unset fields in a1 are +// ignored (not compared). This allows us to focus on the fields that matter to +// the semantic comparison. +// +// The unset fields include a nil pointer and an empty string. +func (e Equalities) DeepDerivative(a1, a2 interface{}) bool { + if a1 == nil { + return true + } + v1 := reflect.ValueOf(a1) + v2 := reflect.ValueOf(a2) + if v1.Type() != v2.Type() { + return false + } + return e.deepValueDerive(v1, v2, make(map[visit]bool), 0) +} diff --git a/vendor/k8s.io/utils/trace/trace.go b/vendor/k8s.io/utils/trace/trace.go new file mode 100644 index 0000000000..3b424104a9 --- /dev/null +++ b/vendor/k8s.io/utils/trace/trace.go @@ -0,0 +1,131 @@ +/* +Copyright 2015 The Kubernetes 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. +*/ + +package trace + +import ( + "bytes" + "fmt" + "math/rand" + "time" + + "k8s.io/klog" +) + +// Field is a key value pair that provides additional details about the trace. +type Field struct { + Key string + Value interface{} +} + +func (f Field) format() string { + return fmt.Sprintf("%s:%v", f.Key, f.Value) +} + +func writeFields(b *bytes.Buffer, l []Field) { + for i, f := range l { + b.WriteString(f.format()) + if i < len(l)-1 { + b.WriteString(",") + } + } +} + +type traceStep struct { + stepTime time.Time + msg string + fields []Field +} + +// Trace keeps track of a set of "steps" and allows us to log a specific +// step if it took longer than its share of the total allowed time +type Trace struct { + name string + fields []Field + startTime time.Time + steps []traceStep +} + +// New creates a Trace with the specified name. The name identifies the operation to be traced. The +// Fields add key value pairs to provide additional details about the trace, such as operation inputs. +func New(name string, fields ...Field) *Trace { + return &Trace{name: name, startTime: time.Now(), fields: fields} +} + +// Step adds a new step with a specific message. Call this at the end of an execution step to record +// how long it took. The Fields add key value pairs to provide additional details about the trace +// step. +func (t *Trace) Step(msg string, fields ...Field) { + if t.steps == nil { + // traces almost always have less than 6 steps, do this to avoid more than a single allocation + t.steps = make([]traceStep, 0, 6) + } + t.steps = append(t.steps, traceStep{stepTime: time.Now(), msg: msg, fields: fields}) +} + +// Log is used to dump all the steps in the Trace +func (t *Trace) Log() { + // an explicit logging request should dump all the steps out at the higher level + t.logWithStepThreshold(0) +} + +func (t *Trace) logWithStepThreshold(stepThreshold time.Duration) { + var buffer bytes.Buffer + tracenum := rand.Int31() + endTime := time.Now() + + totalTime := endTime.Sub(t.startTime) + buffer.WriteString(fmt.Sprintf("Trace[%d]: %q ", tracenum, t.name)) + if len(t.fields) > 0 { + writeFields(&buffer, t.fields) + buffer.WriteString(" ") + } + buffer.WriteString(fmt.Sprintf("(started: %v) (total time: %v):\n", t.startTime, totalTime)) + lastStepTime := t.startTime + for _, step := range t.steps { + stepDuration := step.stepTime.Sub(lastStepTime) + if stepThreshold == 0 || stepDuration > stepThreshold || klog.V(4) { + buffer.WriteString(fmt.Sprintf("Trace[%d]: [%v] [%v] ", tracenum, step.stepTime.Sub(t.startTime), stepDuration)) + buffer.WriteString(step.msg) + if len(step.fields) > 0 { + buffer.WriteString(" ") + writeFields(&buffer, step.fields) + } + buffer.WriteString("\n") + } + lastStepTime = step.stepTime + } + stepDuration := endTime.Sub(lastStepTime) + if stepThreshold == 0 || stepDuration > stepThreshold || klog.V(4) { + buffer.WriteString(fmt.Sprintf("Trace[%d]: [%v] [%v] END\n", tracenum, endTime.Sub(t.startTime), stepDuration)) + } + + klog.Info(buffer.String()) +} + +// LogIfLong is used to dump steps that took longer than its share +func (t *Trace) LogIfLong(threshold time.Duration) { + if time.Since(t.startTime) >= threshold { + // if any step took more than it's share of the total allowed time, it deserves a higher log level + stepThreshold := threshold / time.Duration(len(t.steps)+1) + t.logWithStepThreshold(stepThreshold) + } +} + +// TotalTime can be used to figure out how long it took since the Trace was created +func (t *Trace) TotalTime() time.Duration { + return time.Since(t.startTime) +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/LICENSE b/vendor/kubevirt.io/machine-remediation-operator/LICENSE new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/LICENSE @@ -0,0 +1,201 @@ + 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 + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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/vendor/kubevirt.io/machine-remediation-operator/cmd/machine-disruption-budget/main.go b/vendor/kubevirt.io/machine-remediation-operator/cmd/machine-disruption-budget/main.go new file mode 100644 index 0000000000..19159cb43b --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/cmd/machine-disruption-budget/main.go @@ -0,0 +1,73 @@ +package main + +import ( + "flag" + "runtime" + + "github.com/golang/glog" + mrv1 "kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1" + "kubevirt.io/machine-remediation-operator/pkg/controllers" + disruption "kubevirt.io/machine-remediation-operator/pkg/controllers/machinedisruptionbudget" + "kubevirt.io/machine-remediation-operator/pkg/version" + + mapiv1 "sigs.k8s.io/cluster-api/pkg/apis/machine/v1beta1" + "sigs.k8s.io/controller-runtime/pkg/client/config" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/runtime/signals" +) + +func printVersion() { + glog.Infof("Go Version: %s", runtime.Version()) + glog.Infof("Go OS/Arch: %s/%s", runtime.GOOS, runtime.GOARCH) + glog.Infof("Component version: %s", version.Get()) +} + +func main() { + namespace := flag.String("namespace", "", "Namespace that the controller watches to reconcile objects. If unspecified, the controller watches for machine-disruption-budget objects across all namespaces.") + flag.Parse() + + printVersion() + + // Get a config to talk to the apiserver + cfg, err := config.GetConfig() + if err != nil { + glog.Fatal(err) + } + + opts := manager.Options{ + LeaderElection: true, + LeaderElectionID: "machine-disruption-budget", + } + if *namespace != "" { + opts.LeaderElectionNamespace = *namespace + opts.Namespace = *namespace + glog.Infof("Watching MDB objects only in namespace %q for reconciliation.", opts.Namespace) + } + // Create a new Cmd to provide shared dependencies and start components + mgr, err := manager.New(cfg, opts) + if err != nil { + glog.Fatal(err) + } + + glog.Infof("Registering Components.") + + // Setup Scheme for all resources + if err := mrv1.AddToScheme(mgr.GetScheme()); err != nil { + glog.Fatal(err) + } + if err := mapiv1.AddToScheme(mgr.GetScheme()); err != nil { + glog.Fatal(err) + } + + // Setup all Controllers + if err := controllers.AddToManager(mgr, opts, disruption.Add); err != nil { + glog.Fatal(err) + } + + glog.Info("Starting the Cmd.") + + // Start the Cmd + if err := mgr.Start(signals.SetupSignalHandler()); err != nil { + glog.Fatal(err) + } +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/cmd/machine-health-check/main.go b/vendor/kubevirt.io/machine-remediation-operator/cmd/machine-health-check/main.go new file mode 100644 index 0000000000..5d736418c1 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/cmd/machine-health-check/main.go @@ -0,0 +1,73 @@ +package main + +import ( + "flag" + "runtime" + + "github.com/golang/glog" + mrv1 "kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1" + "kubevirt.io/machine-remediation-operator/pkg/controllers" + "kubevirt.io/machine-remediation-operator/pkg/controllers/machinehealthcheck" + "kubevirt.io/machine-remediation-operator/pkg/version" + + mapiv1 "sigs.k8s.io/cluster-api/pkg/apis/machine/v1beta1" + "sigs.k8s.io/controller-runtime/pkg/client/config" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/runtime/signals" +) + +func printVersion() { + glog.Infof("Go Version: %s", runtime.Version()) + glog.Infof("Go OS/Arch: %s/%s", runtime.GOOS, runtime.GOARCH) + glog.Infof("Component version: %s", version.Get()) +} + +func main() { + namespace := flag.String("namespace", "", "Namespace that the controller watches to reconcile objects. If unspecified, the controller watches for machine-health-check objects across all namespaces.") + flag.Parse() + + printVersion() + + // Get a config to talk to the apiserver + cfg, err := config.GetConfig() + if err != nil { + glog.Fatal(err) + } + + opts := manager.Options{ + LeaderElection: true, + LeaderElectionID: "machine-health-check", + } + if *namespace != "" { + opts.LeaderElectionNamespace = *namespace + opts.Namespace = *namespace + glog.Infof("Watching MHC objects only in namespace %q for reconciliation.", opts.Namespace) + } + // Create a new Cmd to provide shared dependencies and start components + mgr, err := manager.New(cfg, opts) + if err != nil { + glog.Fatal(err) + } + + glog.Infof("Registering Components.") + + // Setup Scheme for all resources + if err := mrv1.AddToScheme(mgr.GetScheme()); err != nil { + glog.Fatal(err) + } + if err := mapiv1.AddToScheme(mgr.GetScheme()); err != nil { + glog.Fatal(err) + } + + // Setup all Controllers + if err := controllers.AddToManager(mgr, opts, machinehealthcheck.Add); err != nil { + glog.Fatal(err) + } + + glog.Info("Starting the Cmd.") + + // Start the Cmd + if err := mgr.Start(signals.SetupSignalHandler()); err != nil { + glog.Fatal(err) + } +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/cmd/machine-remediation-operator/main.go b/vendor/kubevirt.io/machine-remediation-operator/cmd/machine-remediation-operator/main.go new file mode 100644 index 0000000000..1f27797b44 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/cmd/machine-remediation-operator/main.go @@ -0,0 +1,78 @@ +package main + +import ( + "flag" + "runtime" + + "github.com/golang/glog" + + extv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + mrv1 "kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1" + "kubevirt.io/machine-remediation-operator/pkg/consts" + "kubevirt.io/machine-remediation-operator/pkg/controllers" + "kubevirt.io/machine-remediation-operator/pkg/operator" + "kubevirt.io/machine-remediation-operator/pkg/version" + + "sigs.k8s.io/controller-runtime/pkg/cache" + "sigs.k8s.io/controller-runtime/pkg/client/config" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/runtime/signals" +) + +func printVersion() { + glog.Infof("Go Version: %s", runtime.Version()) + glog.Infof("Go OS/Arch: %s/%s", runtime.GOOS, runtime.GOARCH) + glog.Infof("Component version: %s", version.Get()) +} + +func main() { + namespace := flag.String("namespace", "", "Namespace that the controller watches to reconcile objects. If unspecified, the controller watches for machine-remediation-operator objects across all namespaces.") + flag.Parse() + + printVersion() + + // Get a config to talk to the apiserver + cfg, err := config.GetConfig() + if err != nil { + glog.Fatal(err) + } + + namespaces := []string{consts.NamespaceOpenshiftMachineAPI, metav1.NamespaceNone} + if *namespace != "" { + namespaces = append(namespaces, *namespace) + } + opts := manager.Options{ + NewCache: cache.MultiNamespacedCacheBuilder(namespaces), + } + + // Create a new Cmd to provide shared dependencies and start components + mgr, err := manager.New(cfg, opts) + if err != nil { + glog.Fatal(err) + } + + glog.Infof("Registering Components.") + + // Setup Scheme for all resources + if err := extv1beta1.AddToScheme(mgr.GetScheme()); err != nil { + glog.Fatal(err) + } + + if err := mrv1.AddToScheme(mgr.GetScheme()); err != nil { + glog.Fatal(err) + } + + // Setup all Controllers + if err := controllers.AddToManager(mgr, opts, operator.Add); err != nil { + glog.Fatal(err) + } + + glog.Info("Starting the Cmd.") + + // Start the Cmd + if err := mgr.Start(signals.SetupSignalHandler()); err != nil { + glog.Fatal(err) + } +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/cmd/machine-remediation/main.go b/vendor/kubevirt.io/machine-remediation-operator/cmd/machine-remediation/main.go new file mode 100644 index 0000000000..e78901d226 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/cmd/machine-remediation/main.go @@ -0,0 +1,85 @@ +package main + +import ( + "flag" + "runtime" + + "github.com/golang/glog" + bmov1 "github.com/metal3-io/baremetal-operator/pkg/apis/metal3/v1alpha1" + + mrv1 "kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1" + "kubevirt.io/machine-remediation-operator/pkg/baremetal/remediator" + "kubevirt.io/machine-remediation-operator/pkg/controllers" + "kubevirt.io/machine-remediation-operator/pkg/controllers/machineremediation" + "kubevirt.io/machine-remediation-operator/pkg/version" + + mapiv1 "sigs.k8s.io/cluster-api/pkg/apis/machine/v1beta1" + "sigs.k8s.io/controller-runtime/pkg/client/config" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/runtime/signals" +) + +func printVersion() { + glog.Infof("Go Version: %s", runtime.Version()) + glog.Infof("Go OS/Arch: %s/%s", runtime.GOOS, runtime.GOARCH) + glog.Infof("Component version: %s", version.Get()) +} + +func main() { + namespace := flag.String("namespace", "", "Namespace that the controller watches to reconcile objects. If unspecified, the controller watches for machine remediation objects across all namespaces.") + flag.Parse() + + printVersion() + + // Get a config to talk to the apiserver + cfg, err := config.GetConfig() + if err != nil { + glog.Fatal(err) + } + + opts := manager.Options{ + LeaderElection: true, + LeaderElectionID: "machine-remediation", + } + if *namespace != "" { + opts.LeaderElectionNamespace = *namespace + opts.Namespace = *namespace + glog.Infof("Watching machine remediations objects only in namespace %q for reconciliation.", opts.Namespace) + } + + // Create a new Cmd to provide shared dependencies and start components + mgr, err := manager.New(cfg, opts) + if err != nil { + glog.Fatal(err) + } + + glog.Infof("Registering Components.") + + // Setup Scheme for all resources + if err := mrv1.AddToScheme(mgr.GetScheme()); err != nil { + glog.Fatal(err) + } + if err := mapiv1.AddToScheme(mgr.GetScheme()); err != nil { + glog.Fatal(err) + } + if err := bmov1.SchemeBuilder.AddToScheme(mgr.GetScheme()); err != nil { + glog.Fatal(err) + } + + remediator := remediator.NewBareMetalRemediator(mgr) + addController := func(m manager.Manager, opts manager.Options) error { + return machineremediation.AddWithRemediator(m, remediator, opts) + } + + // Setup all Controllers + if err := controllers.AddToManager(mgr, opts, addController); err != nil { + glog.Fatal(err) + } + + glog.Info("Starting the Cmd.") + + // Start the Cmd + if err := mgr.Start(signals.SetupSignalHandler()); err != nil { + glog.Fatal(err) + } +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/register.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/register.go new file mode 100644 index 0000000000..190327f624 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/register.go @@ -0,0 +1,4 @@ +package machineremediation + +// GroupName contains the name of the API group +const GroupName = "machineremediation.kubevirt.io" diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1/doc.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1/doc.go new file mode 100644 index 0000000000..b7f15810f6 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1/doc.go @@ -0,0 +1,4 @@ +// Package v1alpha1 contains API Schema definitions for the healthchecking v1alpha1 API group +// +k8s:deepcopy-gen=package,register +// +groupName=machineremediation.kubevirt.io +package v1alpha1 diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1/machinedisruptionbudget_types.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1/machinedisruptionbudget_types.go new file mode 100644 index 0000000000..3fb942761d --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1/machinedisruptionbudget_types.go @@ -0,0 +1,94 @@ +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// MachineDisruptionBudgetSpec is a description of a MachineDisruptionBudget. +type MachineDisruptionBudgetSpec struct { + // An deletion of the machine is allowed if at least "minAvailable" machines selected by + // "selector" will still be available after the deletion. + // So for example you can prevent all voluntary deletions by specifying all available nodes. + // +optional + MinAvailable *int32 `json:"minAvailable,omitempty" protobuf:"bytes,1,opt,name=minAvailable"` + + // Label query over machines whose deletions are managed by the disruption + // budget. + // +optional + // +kubebuilder:validation:Minimum=0 + Selector *metav1.LabelSelector `json:"selector,omitempty" protobuf:"bytes,2,opt,name=selector"` + + // An deletion is allowed if at most "maxUnavailable" machines selected by + // "selector" are unavailable after the deletion. + // For example, one can prevent all voluntary deletions by specifying 0. + // This is a mutually exclusive setting with "minAvailable". + // +optional + // +kubebuilder:validation:Minimum=0 + MaxUnavailable *int32 `json:"maxUnavailable,omitempty" protobuf:"bytes,3,opt,name=maxUnavailable"` +} + +// MachineDisruptionBudgetStatus represents information about the status of a +// MachineDisruptionBudget. Status may trail the actual state of a system. +type MachineDisruptionBudgetStatus struct { + // Most recent generation observed when updating this MDB status. MachineDisruptionsAllowed and other + // status information is valid only if observedGeneration equals to MDB's object generation. + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty" protobuf:"varint,1,opt,name=observedGeneration"` + + // DisruptedMachines contains information about machines whose deletion was + // processed by the API server but has not yet been observed by the MachineDisruptionBudget controller. + // A machine will be in this map from the time when the API server processed the + // deletion request to the time when the machine is seen by MDB controller + // as having been marked for deletion (or after a timeout). The key in the map is the name of the machine + // and the value is the time when the API server processed the deletion request. If + // the deletion didn't occur and a machine is still there it will be removed from + // the list automatically by MachineDisruptionBudget controller after some time. + // If everything goes smooth this map should be empty for the most of the time. + // Large number of entries in the map may indicate problems with machines deletions. + // +optional + DisruptedMachines map[string]metav1.Time `json:"disruptedMachines,omitempty" protobuf:"bytes,2,rep,name=DisruptedMachines"` + + // Number of machines disruptions that are currently allowed. + MachineDisruptionsAllowed int32 `json:"disruptionsAllowed" protobuf:"varint,3,opt,name=disruptionsAllowed"` + + // current number of healthy machines + CurrentHealthy int32 `json:"currentHealthy" protobuf:"varint,4,opt,name=currentHealthy"` + + // minimum desired number of healthy machines + DesiredHealthy int32 `json:"desiredHealthy" protobuf:"varint,5,opt,name=desiredHealthy"` + + // total number of machines counted by this disruption budget + Total int32 `json:"total" protobuf:"varint,6,opt,name=total"` +} + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// MachineDisruptionBudget is an object to define the max disruption that a collection of machines can experience +// +kubebuilder:subresource:status +// +kubebuilder:resource:shortName=mdb;mdbs +// +kubebuilder:printcolumn:name="Healthy",type="integer",JSONPath=".status.currentHealthy",description="The number of healthy machines" +// +kubebuilder:printcolumn:name="Total",type="integer",JSONPath=".status.total",description="The total number of machines" +// +kubebuilder:printcolumn:name="Desired",type="integer",JSONPath=".status.desiredHealthy",description="The desired number of healthy machines" +type MachineDisruptionBudget struct { + metav1.TypeMeta `json:",inline"` + // +optional + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // Specification of the desired behavior of the MachineDisruptionBudget. + // +optional + Spec MachineDisruptionBudgetSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` + // Most recently observed status of the MachineDisruptionBudget. + // +optional + Status MachineDisruptionBudgetStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// MachineDisruptionBudgetList is a collection of MachineDisruptionBudgets. +type MachineDisruptionBudgetList struct { + metav1.TypeMeta `json:",inline"` + // +optional + metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + Items []MachineDisruptionBudget `json:"items" protobuf:"bytes,2,rep,name=items"` +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1/machinehealthcheck_types.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1/machinehealthcheck_types.go new file mode 100644 index 0000000000..03c0cfe7ca --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1/machinehealthcheck_types.go @@ -0,0 +1,59 @@ +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// ConfigMapNodeUnhealthyConditions contains the name of the unhealthy conditions config map +const ConfigMapNodeUnhealthyConditions = "node-unhealthy-conditions" + +// RemediationStrategyType contains type of the remediation that we are wanting to use +type RemediationStrategyType string + +const ( + // RemediationStrategyTypeReboot contains name of the reboot remediation strategy + RemediationStrategyTypeReboot = "Reboot" + // RemediationStrategyTypeReCreate contains name of the re-create remediation strategy + RemediationStrategyTypeReCreate = "ReCreate" +) + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// MachineHealthCheck is the Schema for the machinehealthchecks API +// +kubebuilder:subresource:status +// +kubebuilder:resource:shortName=mhc;mhcs +// +k8s:openapi-gen=true +type MachineHealthCheck struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Specification of machine health check policy + Spec MachineHealthCheckSpec `json:"spec,omitempty"` + + // Most recently observed status of MachineHealthCheck resource + Status MachineHealthCheckStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// MachineHealthCheckList contains a list of MachineHealthCheck +type MachineHealthCheckList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []MachineHealthCheck `json:"items"` +} + +// MachineHealthCheckSpec defines the desired state of MachineHealthCheck +type MachineHealthCheckSpec struct { + // RemediationStrategy to use in case of problem detection + // default is machine deletion + RemediationStrategy *RemediationStrategyType `json:"remediationStrategy,omitempty"` + // Label selector to match machines whose health will be exercised + Selector metav1.LabelSelector `json:"selector"` +} + +// MachineHealthCheckStatus defines the observed state of MachineHealthCheck +type MachineHealthCheckStatus struct { + // TODO(alberto) +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1/machineremediation_types.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1/machineremediation_types.go new file mode 100644 index 0000000000..d30e6e06a5 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1/machineremediation_types.go @@ -0,0 +1,74 @@ +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// RemediationType contains type of the remediation +type RemediationType string + +const ( + // RemediationTypeReboot contains reboot type of the remediation + RemediationTypeReboot RemediationType = "Reboot" + // RemediationTypeRecreate contains re-create type of the remediation + RemediationTypeRecreate RemediationType = "Re-Create" +) + +// RemediationState contains state of the remediation +type RemediationState string + +const ( + // RemediationStateStarted contains remediation state when the machine remediation object was created + RemediationStateStarted RemediationState = "Started" + // RemediationStatePowerOff contains remediation state when the host power offed by the controller + RemediationStatePowerOff RemediationState = "PowerOff" + // RemediationStatePowerOn contains remediation state when the host power oned again by the controller + RemediationStatePowerOn RemediationState = "PowerOn" + // RemediationStateSucceeded contains remediation state when the operation succeeded + RemediationStateSucceeded RemediationState = "Succeeded" + // RemediationStateFailed contains remediation state when the operation failed + RemediationStateFailed RemediationState = "Failed" +) + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// MachineRemediation is the schema for the MachineRemediation API +// +kubebuilder:subresource:status +// +kubebuilder:resource:shortName=mr;mrs +// +k8s:openapi-gen=true +type MachineRemediation struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Specification of MachineRemediation + Spec MachineRemediationSpec `json:"spec,omitempty"` + + // Most recently observed status of MachineRemediation resource + Status MachineRemediationStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// MachineRemediationList contains a list of MachineRemediation +type MachineRemediationList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []MachineRemediation `json:"items"` +} + +// MachineRemediationSpec defines the spec of MachineRemediation +type MachineRemediationSpec struct { + // Type contains the type of the remediation + Type RemediationType `json:"type,omitempty" valid:"required"` + // MachineName contains the name of machine that should be remediate + MachineName string `json:"machineName,omitempty" valid:"required"` +} + +// MachineRemediationStatus defines the observed status of MachineRemediation +type MachineRemediationStatus struct { + State RemediationState `json:"state,omitempty"` + Reason string `json:"reason,omitempty"` + StartTime *metav1.Time `json:"startTime,omitempty"` + EndTime *metav1.Time `json:"endTime,omitempty"` +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1/machineremediationoperator_types.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1/machineremediationoperator_types.go new file mode 100644 index 0000000000..c11cf8ea16 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1/machineremediationoperator_types.go @@ -0,0 +1,87 @@ +package v1alpha1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// OperatorConditionType is the state of the operator's reconciliation functionality. +type OperatorConditionType string + +const ( + // OperatorAvailable indicates that the binary maintained by the operator is functional and available in the cluster. + OperatorAvailable OperatorConditionType = "Available" + + // OperatorProgressing indicates that the operator is actively making changes to the binary maintained by the operator. + OperatorProgressing OperatorConditionType = "Progressing" + + // OperatorDegraded indicates that the operand is not functioning completely. An example of a degraded state + // would be if there should be 5 copies of the operand running but only 4 are running. It may still be available, + // but it is degraded + OperatorDegraded OperatorConditionType = "Degraded" +) + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// MachineRemediationOperator is the schema for the MachineRemediationOperator API +// +kubebuilder:subresource:status +// +kubebuilder:resource:shortName=mro;mros +// +k8s:openapi-gen=true +type MachineRemediationOperator struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Specification of MachineRemediationOperator + Spec MachineRemediationOperatorSpec `json:"spec,omitempty"` + + // Most recently observed status of MachineRemediationOperator resource + Status MachineRemediationOperatorStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// MachineRemediationOperatorList contains a list of MachineRemediationOperator +type MachineRemediationOperatorList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []MachineRemediationOperator `json:"items"` +} + +// MachineRemediationOperatorSpec defines the spec of MachineRemediation +type MachineRemediationOperatorSpec struct { + // The image registry to pull the container images from + // Defaults to the same registry the operator's container image is pulled from. + ImageRegistry string `json:"imageRegistry,omitempty"` + // The ImagePullPolicy to use. + ImagePullPolicy corev1.PullPolicy `json:"imagePullPolicy,omitempty" valid:"required"` +} + +// MachineRemediationOperatorStatus defines the observed status of MachineRemediationOperator +type MachineRemediationOperatorStatus struct { + // type specifies the state of the operator's reconciliation functionality, + // which reflects the state of the application + Conditions []MachineRemediationOperatorStatusCondition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"` +} + +// MachineRemediationOperatorStatusCondition represents the state of the operator's +// reconciliation functionality. +// +k8s:deepcopy-gen=true +type MachineRemediationOperatorStatusCondition struct { + // type specifies the state of the operator's reconciliation functionality, + // which reflects the state of the application + Type OperatorConditionType `json:"type"` + + // status of the condition, one either True or False. + Status corev1.ConditionStatus `json:"status"` + + // lastTransitionTime is the time of the last update to the current status object. + LastTransitionTime metav1.Time `json:"lastTransitionTime"` + + // reason is the reason for the condition's last transition. Reasons are CamelCase + Reason string `json:"reason,omitempty"` + + // message provides additional information about the current condition. + // This is only to be consumed by humans. + Message string `json:"message,omitempty"` +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1/register.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1/register.go new file mode 100644 index 0000000000..894661e574 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1/register.go @@ -0,0 +1,50 @@ +// NOTE: Boilerplate only. Ignore this file. + +// Package v1alpha1 contains API Schema definitions for the healthchecking v1alpha1 API group +// +k8s:deepcopy-gen=package,register +// +groupName=machineremediation.kubevirt.io +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + + "kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation" +) + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: machineremediation.GroupName, Version: "v1alpha1"} + +// 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 contains SchemeBuilder function + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + // AddToScheme contains AddToScheme method + AddToScheme = SchemeBuilder.AddToScheme +) + +// Adds the list of known types to Scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &MachineDisruptionBudget{}, + &MachineDisruptionBudgetList{}, + &MachineHealthCheck{}, + &MachineHealthCheckList{}, + &MachineRemediation{}, + &MachineRemediationList{}, + &MachineRemediationOperator{}, + &MachineRemediationOperatorList{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1/zz_generated.deepcopy.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 0000000000..fab7228d08 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,458 @@ +// +build !ignore_autogenerated + +/* + * 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. + * + * Copyright 2019 Red Hat, Inc. + * + */ +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + 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 *MachineDisruptionBudget) DeepCopyInto(out *MachineDisruptionBudget) { + *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 MachineDisruptionBudget. +func (in *MachineDisruptionBudget) DeepCopy() *MachineDisruptionBudget { + if in == nil { + return nil + } + out := new(MachineDisruptionBudget) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *MachineDisruptionBudget) 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 *MachineDisruptionBudgetList) DeepCopyInto(out *MachineDisruptionBudgetList) { + *out = *in + out.TypeMeta = in.TypeMeta + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]MachineDisruptionBudget, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineDisruptionBudgetList. +func (in *MachineDisruptionBudgetList) DeepCopy() *MachineDisruptionBudgetList { + if in == nil { + return nil + } + out := new(MachineDisruptionBudgetList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *MachineDisruptionBudgetList) 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 *MachineDisruptionBudgetSpec) DeepCopyInto(out *MachineDisruptionBudgetSpec) { + *out = *in + if in.MinAvailable != nil { + in, out := &in.MinAvailable, &out.MinAvailable + *out = new(int32) + **out = **in + } + if in.Selector != nil { + in, out := &in.Selector, &out.Selector + *out = new(v1.LabelSelector) + (*in).DeepCopyInto(*out) + } + if in.MaxUnavailable != nil { + in, out := &in.MaxUnavailable, &out.MaxUnavailable + *out = new(int32) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineDisruptionBudgetSpec. +func (in *MachineDisruptionBudgetSpec) DeepCopy() *MachineDisruptionBudgetSpec { + if in == nil { + return nil + } + out := new(MachineDisruptionBudgetSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MachineDisruptionBudgetStatus) DeepCopyInto(out *MachineDisruptionBudgetStatus) { + *out = *in + if in.DisruptedMachines != nil { + in, out := &in.DisruptedMachines, &out.DisruptedMachines + *out = make(map[string]v1.Time, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineDisruptionBudgetStatus. +func (in *MachineDisruptionBudgetStatus) DeepCopy() *MachineDisruptionBudgetStatus { + if in == nil { + return nil + } + out := new(MachineDisruptionBudgetStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MachineHealthCheck) DeepCopyInto(out *MachineHealthCheck) { + *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 MachineHealthCheck. +func (in *MachineHealthCheck) DeepCopy() *MachineHealthCheck { + if in == nil { + return nil + } + out := new(MachineHealthCheck) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *MachineHealthCheck) 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 *MachineHealthCheckList) DeepCopyInto(out *MachineHealthCheckList) { + *out = *in + out.TypeMeta = in.TypeMeta + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]MachineHealthCheck, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineHealthCheckList. +func (in *MachineHealthCheckList) DeepCopy() *MachineHealthCheckList { + if in == nil { + return nil + } + out := new(MachineHealthCheckList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *MachineHealthCheckList) 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 *MachineHealthCheckSpec) DeepCopyInto(out *MachineHealthCheckSpec) { + *out = *in + if in.RemediationStrategy != nil { + in, out := &in.RemediationStrategy, &out.RemediationStrategy + *out = new(RemediationStrategyType) + **out = **in + } + in.Selector.DeepCopyInto(&out.Selector) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineHealthCheckSpec. +func (in *MachineHealthCheckSpec) DeepCopy() *MachineHealthCheckSpec { + if in == nil { + return nil + } + out := new(MachineHealthCheckSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MachineHealthCheckStatus) DeepCopyInto(out *MachineHealthCheckStatus) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineHealthCheckStatus. +func (in *MachineHealthCheckStatus) DeepCopy() *MachineHealthCheckStatus { + if in == nil { + return nil + } + out := new(MachineHealthCheckStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MachineRemediation) DeepCopyInto(out *MachineRemediation) { + *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 MachineRemediation. +func (in *MachineRemediation) DeepCopy() *MachineRemediation { + if in == nil { + return nil + } + out := new(MachineRemediation) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *MachineRemediation) 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 *MachineRemediationList) DeepCopyInto(out *MachineRemediationList) { + *out = *in + out.TypeMeta = in.TypeMeta + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]MachineRemediation, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineRemediationList. +func (in *MachineRemediationList) DeepCopy() *MachineRemediationList { + if in == nil { + return nil + } + out := new(MachineRemediationList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *MachineRemediationList) 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 *MachineRemediationOperator) DeepCopyInto(out *MachineRemediationOperator) { + *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 MachineRemediationOperator. +func (in *MachineRemediationOperator) DeepCopy() *MachineRemediationOperator { + if in == nil { + return nil + } + out := new(MachineRemediationOperator) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *MachineRemediationOperator) 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 *MachineRemediationOperatorList) DeepCopyInto(out *MachineRemediationOperatorList) { + *out = *in + out.TypeMeta = in.TypeMeta + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]MachineRemediationOperator, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineRemediationOperatorList. +func (in *MachineRemediationOperatorList) DeepCopy() *MachineRemediationOperatorList { + if in == nil { + return nil + } + out := new(MachineRemediationOperatorList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *MachineRemediationOperatorList) 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 *MachineRemediationOperatorSpec) DeepCopyInto(out *MachineRemediationOperatorSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineRemediationOperatorSpec. +func (in *MachineRemediationOperatorSpec) DeepCopy() *MachineRemediationOperatorSpec { + if in == nil { + return nil + } + out := new(MachineRemediationOperatorSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MachineRemediationOperatorStatus) DeepCopyInto(out *MachineRemediationOperatorStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]MachineRemediationOperatorStatusCondition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineRemediationOperatorStatus. +func (in *MachineRemediationOperatorStatus) DeepCopy() *MachineRemediationOperatorStatus { + if in == nil { + return nil + } + out := new(MachineRemediationOperatorStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MachineRemediationOperatorStatusCondition) DeepCopyInto(out *MachineRemediationOperatorStatusCondition) { + *out = *in + in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineRemediationOperatorStatusCondition. +func (in *MachineRemediationOperatorStatusCondition) DeepCopy() *MachineRemediationOperatorStatusCondition { + if in == nil { + return nil + } + out := new(MachineRemediationOperatorStatusCondition) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MachineRemediationSpec) DeepCopyInto(out *MachineRemediationSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineRemediationSpec. +func (in *MachineRemediationSpec) DeepCopy() *MachineRemediationSpec { + if in == nil { + return nil + } + out := new(MachineRemediationSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MachineRemediationStatus) DeepCopyInto(out *MachineRemediationStatus) { + *out = *in + if in.StartTime != nil { + in, out := &in.StartTime, &out.StartTime + *out = (*in).DeepCopy() + } + if in.EndTime != nil { + in, out := &in.EndTime, &out.EndTime + *out = (*in).DeepCopy() + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineRemediationStatus. +func (in *MachineRemediationStatus) DeepCopy() *MachineRemediationStatus { + if in == nil { + return nil + } + out := new(MachineRemediationStatus) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/baremetal/remediator/remediator.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/baremetal/remediator/remediator.go new file mode 100644 index 0000000000..d1fca5b648 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/baremetal/remediator/remediator.go @@ -0,0 +1,217 @@ +package remediator + +import ( + "context" + "fmt" + "time" + + "github.com/golang/glog" + bmov1 "github.com/metal3-io/baremetal-operator/pkg/apis/metal3/v1alpha1" + mrv1 "kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1" + "kubevirt.io/machine-remediation-operator/pkg/consts" + "kubevirt.io/machine-remediation-operator/pkg/utils/conditions" + + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/tools/cache" + + mapiv1 "sigs.k8s.io/cluster-api/pkg/apis/machine/v1beta1" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/manager" +) + +const ( + rebootDefaultTimeout = 5 +) + +// BareMetalRemediator implements Remediator interface for bare metal machines +type BareMetalRemediator struct { + client client.Client +} + +// NewBareMetalRemediator returns new BareMetalRemediator object +func NewBareMetalRemediator(mgr manager.Manager) *BareMetalRemediator { + return &BareMetalRemediator{ + client: mgr.GetClient(), + } +} + +// Recreate recreates the bare metal machine under the cluster +func (bmr *BareMetalRemediator) Recreate(ctx context.Context, machineRemediation *mrv1.MachineRemediation) error { + return fmt.Errorf("Not implemented yet") +} + +// Reboot reboots the bare metal machine +func (bmr *BareMetalRemediator) Reboot(ctx context.Context, machineRemediation *mrv1.MachineRemediation) error { + glog.V(4).Infof("MachineRemediation %q has state %q", machineRemediation.Name, machineRemediation.Status.State) + + // Get the machine from the MachineRemediation + key := types.NamespacedName{ + Namespace: machineRemediation.Namespace, + Name: machineRemediation.Spec.MachineName, + } + machine := &mapiv1.Machine{} + if err := bmr.client.Get(context.TODO(), key, machine); err != nil { + return err + } + + // Get the bare metal host object + bmh, err := getBareMetalHostByMachine(bmr.client, machine) + if err != nil { + return err + } + + // Copy the BareMetalHost object to prevent modification of the original one + bmhCopy := bmh.DeepCopy() + + // Copy the MachineRemediation object to prevent modification of the original one + mrCopy := machineRemediation.DeepCopy() + + now := time.Now() + switch machineRemediation.Status.State { + // initiating the reboot action + case mrv1.RemediationStateStarted: + // skip the reboot in case when the machine has power off state before the reboot action + // it can mean that an user power off the machine by purpose + if !bmh.Spec.Online { + glog.V(4).Infof("Skip the remediation, machine %q has power off state before the remediation action", machine.Name) + mrCopy.Status.State = mrv1.RemediationStateSucceeded + mrCopy.Status.Reason = "Skip the reboot, the machine power off by an user" + mrCopy.Status.EndTime = &metav1.Time{Time: now} + } else { + // power off the machine + glog.V(4).Infof("Power off machine %q", machine.Name) + bmhCopy.Spec.Online = false + if err := bmr.client.Update(context.TODO(), bmhCopy); err != nil { + return err + } + + mrCopy.Status.State = mrv1.RemediationStatePowerOff + mrCopy.Status.Reason = "Starts the reboot process" + } + return bmr.client.Status().Update(context.TODO(), mrCopy) + + case mrv1.RemediationStatePowerOff: + // failed the remediation on timeout + if machineRemediation.Status.StartTime.Time.Add(rebootDefaultTimeout * time.Minute).Before(now) { + glog.Errorf("Remediation of machine %q failed on timeout", machine.Name) + mrCopy.Status.State = mrv1.RemediationStateFailed + mrCopy.Status.Reason = "Reboot failed on timeout" + mrCopy.Status.EndTime = &metav1.Time{Time: now} + return bmr.client.Status().Update(context.TODO(), mrCopy) + } + + // host still has state on, we need to reconcile + if bmh.Status.PoweredOn { + glog.Warningf("machine %q still has power on state", machine.Name) + return nil + } + + // delete the node to release workloads, once we are sure that host has state power off + if err := deleteMachineNode(bmr.client, machine); err != nil { + return err + } + + // power on the machine + glog.V(4).Infof("Power on machine %q", machine.Name) + bmhCopy.Spec.Online = true + if err := bmr.client.Update(context.TODO(), bmhCopy); err != nil { + return err + } + + mrCopy.Status.State = mrv1.RemediationStatePowerOn + mrCopy.Status.Reason = "Reboot in progress" + return bmr.client.Status().Update(context.TODO(), mrCopy) + + case mrv1.RemediationStatePowerOn: + // failed the remediation on timeout + if machineRemediation.Status.StartTime.Time.Add(rebootDefaultTimeout * time.Minute).Before(now) { + glog.Errorf("Remediation of machine %q failed on timeout", machine.Name) + mrCopy.Status.State = mrv1.RemediationStateFailed + mrCopy.Status.Reason = "Reboot failed on timeout" + mrCopy.Status.EndTime = &metav1.Time{Time: now} + return bmr.client.Status().Update(context.TODO(), mrCopy) + } + + node, err := getNodeByMachine(bmr.client, machine) + if err != nil { + // we want to reconcile with delay of 10 seconds when the machine does not have node reference + // or node does not exist + if errors.IsNotFound(err) { + glog.Warningf("The machine %q node does not exist", machine.Name) + return nil + } + return err + } + + // Node back to Ready under the cluster + if conditions.NodeHasCondition(node, corev1.NodeReady, corev1.ConditionTrue) { + glog.V(4).Infof("Remediation of machine %q succeeded", machine.Name) + mrCopy.Status.State = mrv1.RemediationStateSucceeded + mrCopy.Status.Reason = "Reboot succeeded" + mrCopy.Status.EndTime = &metav1.Time{Time: now} + return bmr.client.Status().Update(context.TODO(), mrCopy) + } + return nil + + case mrv1.RemediationStateSucceeded: + // remove machine remediation object + return bmr.client.Delete(context.TODO(), machineRemediation) + } + return nil +} + +// getBareMetalHostByMachine returns the bare metal host that linked to the machine +func getBareMetalHostByMachine(c client.Client, machine *mapiv1.Machine) (*bmov1.BareMetalHost, error) { + bmhKey, ok := machine.Annotations[consts.AnnotationBareMetalHost] + if !ok { + return nil, fmt.Errorf("machine does not have bare metal host annotation") + } + + bmhNamespace, bmhName, err := cache.SplitMetaNamespaceKey(bmhKey) + bmh := &bmov1.BareMetalHost{} + key := client.ObjectKey{ + Name: bmhName, + Namespace: bmhNamespace, + } + + err = c.Get(context.TODO(), key, bmh) + if err != nil { + return nil, err + } + return bmh, nil +} + +// getNodeByMachine returns the node object referenced by machine +func getNodeByMachine(c client.Client, machine *mapiv1.Machine) (*corev1.Node, error) { + if machine.Status.NodeRef == nil { + return nil, errors.NewNotFound(corev1.Resource("ObjectReference"), machine.Name) + } + + node := &corev1.Node{} + key := client.ObjectKey{ + Name: machine.Status.NodeRef.Name, + Namespace: machine.Status.NodeRef.Namespace, + } + + if err := c.Get(context.TODO(), key, node); err != nil { + return nil, err + } + return node, nil +} + +// deleteMachineNode deletes the node that mapped to specified machine +func deleteMachineNode(c client.Client, machine *mapiv1.Machine) error { + node, err := getNodeByMachine(c, machine) + if err != nil { + if errors.IsNotFound(err) { + glog.Warningf("The machine %q node does not exist", machine.Name) + return nil + } + return err + } + + return c.Delete(context.TODO(), node) +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/clientset.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/clientset.go new file mode 100644 index 0000000000..85a8c34067 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/clientset.go @@ -0,0 +1,90 @@ +/* + * 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. + * + * Copyright 2019 Red Hat, Inc. + * + */ +// Code generated by client-gen. DO NOT EDIT. + +package versioned + +import ( + discovery "k8s.io/client-go/discovery" + rest "k8s.io/client-go/rest" + flowcontrol "k8s.io/client-go/util/flowcontrol" + machineremediationv1alpha1 "kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1" +) + +type Interface interface { + Discovery() discovery.DiscoveryInterface + MachineremediationV1alpha1() machineremediationv1alpha1.MachineremediationV1alpha1Interface +} + +// Clientset contains the clients for groups. Each group has exactly one +// version included in a Clientset. +type Clientset struct { + *discovery.DiscoveryClient + machineremediationV1alpha1 *machineremediationv1alpha1.MachineremediationV1alpha1Client +} + +// MachineremediationV1alpha1 retrieves the MachineremediationV1alpha1Client +func (c *Clientset) MachineremediationV1alpha1() machineremediationv1alpha1.MachineremediationV1alpha1Interface { + return c.machineremediationV1alpha1 +} + +// 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. +func NewForConfig(c *rest.Config) (*Clientset, error) { + configShallowCopy := *c + if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 { + configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst) + } + var cs Clientset + var err error + cs.machineremediationV1alpha1, err = machineremediationv1alpha1.NewForConfig(&configShallowCopy) + if err != nil { + return nil, err + } + + cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy) + 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 { + var cs Clientset + cs.machineremediationV1alpha1 = machineremediationv1alpha1.NewForConfigOrDie(c) + + cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c) + return &cs +} + +// New creates a new Clientset for the given RESTClient. +func New(c rest.Interface) *Clientset { + var cs Clientset + cs.machineremediationV1alpha1 = machineremediationv1alpha1.New(c) + + cs.DiscoveryClient = discovery.NewDiscoveryClient(c) + return &cs +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/doc.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/doc.go new file mode 100644 index 0000000000..955e667a69 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/doc.go @@ -0,0 +1,20 @@ +/* + * 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. + * + * Copyright 2019 Red Hat, Inc. + * + */ +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated clientset. +package versioned diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/fake/clientset_generated.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/fake/clientset_generated.go new file mode 100644 index 0000000000..8ae9d81d9e --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/fake/clientset_generated.go @@ -0,0 +1,77 @@ +/* + * 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. + * + * Copyright 2019 Red Hat, Inc. + * + */ +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "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" + clientset "kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned" + machineremediationv1alpha1 "kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1" + fakemachineremediationv1alpha1 "kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/fake" +) + +// 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{} + 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 +} + +func (c *Clientset) Discovery() discovery.DiscoveryInterface { + return c.discovery +} + +var _ clientset.Interface = &Clientset{} + +// MachineremediationV1alpha1 retrieves the MachineremediationV1alpha1Client +func (c *Clientset) MachineremediationV1alpha1() machineremediationv1alpha1.MachineremediationV1alpha1Interface { + return &fakemachineremediationv1alpha1.FakeMachineremediationV1alpha1{Fake: &c.Fake} +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/fake/doc.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/fake/doc.go new file mode 100644 index 0000000000..e38bd9f036 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/fake/doc.go @@ -0,0 +1,20 @@ +/* + * 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. + * + * Copyright 2019 Red Hat, Inc. + * + */ +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated fake clientset. +package fake diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/fake/register.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/fake/register.go new file mode 100644 index 0000000000..028080c879 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/fake/register.go @@ -0,0 +1,56 @@ +/* + * 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. + * + * Copyright 2019 Red Hat, Inc. + * + */ +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + 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" + machineremediationv1alpha1 "kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1" +) + +var scheme = runtime.NewScheme() +var codecs = serializer.NewCodecFactory(scheme) +var parameterCodec = runtime.NewParameterCodec(scheme) +var localSchemeBuilder = runtime.SchemeBuilder{ + machineremediationv1alpha1.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/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/scheme/doc.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/scheme/doc.go new file mode 100644 index 0000000000..35df78e9c4 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/scheme/doc.go @@ -0,0 +1,20 @@ +/* + * 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. + * + * Copyright 2019 Red Hat, Inc. + * + */ +// Code generated by client-gen. DO NOT EDIT. + +// This package contains the scheme of the automatically generated clientset. +package scheme diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/scheme/register.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/scheme/register.go new file mode 100644 index 0000000000..fdceb4e9c0 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/scheme/register.go @@ -0,0 +1,56 @@ +/* + * 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. + * + * Copyright 2019 Red Hat, Inc. + * + */ +// Code generated by client-gen. DO NOT EDIT. + +package scheme + +import ( + 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" + machineremediationv1alpha1 "kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1" +) + +var Scheme = runtime.NewScheme() +var Codecs = serializer.NewCodecFactory(Scheme) +var ParameterCodec = runtime.NewParameterCodec(Scheme) +var localSchemeBuilder = runtime.SchemeBuilder{ + machineremediationv1alpha1.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/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/doc.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/doc.go new file mode 100644 index 0000000000..0ef4a874d5 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/doc.go @@ -0,0 +1,20 @@ +/* + * 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. + * + * Copyright 2019 Red Hat, Inc. + * + */ +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v1alpha1 diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/fake/doc.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/fake/doc.go new file mode 100644 index 0000000000..3b87edc967 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/fake/doc.go @@ -0,0 +1,20 @@ +/* + * 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. + * + * Copyright 2019 Red Hat, Inc. + * + */ +// Code generated by client-gen. DO NOT EDIT. + +// Package fake has the automatically generated clients. +package fake diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/fake/fake_machinedisruptionbudget.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/fake/fake_machinedisruptionbudget.go new file mode 100644 index 0000000000..73e107de75 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/fake/fake_machinedisruptionbudget.go @@ -0,0 +1,140 @@ +/* + * 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. + * + * Copyright 2019 Red Hat, Inc. + * + */ +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + schema "k8s.io/apimachinery/pkg/runtime/schema" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" + v1alpha1 "kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1" +) + +// FakeMachineDisruptionBudgets implements MachineDisruptionBudgetInterface +type FakeMachineDisruptionBudgets struct { + Fake *FakeMachineremediationV1alpha1 + ns string +} + +var machinedisruptionbudgetsResource = schema.GroupVersionResource{Group: "machineremediation.kubevirt.io", Version: "v1alpha1", Resource: "machinedisruptionbudgets"} + +var machinedisruptionbudgetsKind = schema.GroupVersionKind{Group: "machineremediation.kubevirt.io", Version: "v1alpha1", Kind: "MachineDisruptionBudget"} + +// Get takes name of the machineDisruptionBudget, and returns the corresponding machineDisruptionBudget object, and an error if there is any. +func (c *FakeMachineDisruptionBudgets) Get(name string, options v1.GetOptions) (result *v1alpha1.MachineDisruptionBudget, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(machinedisruptionbudgetsResource, c.ns, name), &v1alpha1.MachineDisruptionBudget{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.MachineDisruptionBudget), err +} + +// List takes label and field selectors, and returns the list of MachineDisruptionBudgets that match those selectors. +func (c *FakeMachineDisruptionBudgets) List(opts v1.ListOptions) (result *v1alpha1.MachineDisruptionBudgetList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(machinedisruptionbudgetsResource, machinedisruptionbudgetsKind, c.ns, opts), &v1alpha1.MachineDisruptionBudgetList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1alpha1.MachineDisruptionBudgetList{ListMeta: obj.(*v1alpha1.MachineDisruptionBudgetList).ListMeta} + for _, item := range obj.(*v1alpha1.MachineDisruptionBudgetList).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 machineDisruptionBudgets. +func (c *FakeMachineDisruptionBudgets) Watch(opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(machinedisruptionbudgetsResource, c.ns, opts)) + +} + +// Create takes the representation of a machineDisruptionBudget and creates it. Returns the server's representation of the machineDisruptionBudget, and an error, if there is any. +func (c *FakeMachineDisruptionBudgets) Create(machineDisruptionBudget *v1alpha1.MachineDisruptionBudget) (result *v1alpha1.MachineDisruptionBudget, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(machinedisruptionbudgetsResource, c.ns, machineDisruptionBudget), &v1alpha1.MachineDisruptionBudget{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.MachineDisruptionBudget), err +} + +// Update takes the representation of a machineDisruptionBudget and updates it. Returns the server's representation of the machineDisruptionBudget, and an error, if there is any. +func (c *FakeMachineDisruptionBudgets) Update(machineDisruptionBudget *v1alpha1.MachineDisruptionBudget) (result *v1alpha1.MachineDisruptionBudget, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(machinedisruptionbudgetsResource, c.ns, machineDisruptionBudget), &v1alpha1.MachineDisruptionBudget{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.MachineDisruptionBudget), 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 *FakeMachineDisruptionBudgets) UpdateStatus(machineDisruptionBudget *v1alpha1.MachineDisruptionBudget) (*v1alpha1.MachineDisruptionBudget, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(machinedisruptionbudgetsResource, "status", c.ns, machineDisruptionBudget), &v1alpha1.MachineDisruptionBudget{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.MachineDisruptionBudget), err +} + +// Delete takes name of the machineDisruptionBudget and deletes it. Returns an error if one occurs. +func (c *FakeMachineDisruptionBudgets) Delete(name string, options *v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteAction(machinedisruptionbudgetsResource, c.ns, name), &v1alpha1.MachineDisruptionBudget{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeMachineDisruptionBudgets) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(machinedisruptionbudgetsResource, c.ns, listOptions) + + _, err := c.Fake.Invokes(action, &v1alpha1.MachineDisruptionBudgetList{}) + return err +} + +// Patch applies the patch and returns the patched machineDisruptionBudget. +func (c *FakeMachineDisruptionBudgets) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.MachineDisruptionBudget, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(machinedisruptionbudgetsResource, c.ns, name, pt, data, subresources...), &v1alpha1.MachineDisruptionBudget{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.MachineDisruptionBudget), err +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/fake/fake_machinehealthcheck.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/fake/fake_machinehealthcheck.go new file mode 100644 index 0000000000..ef01555bbe --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/fake/fake_machinehealthcheck.go @@ -0,0 +1,140 @@ +/* + * 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. + * + * Copyright 2019 Red Hat, Inc. + * + */ +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + schema "k8s.io/apimachinery/pkg/runtime/schema" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" + v1alpha1 "kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1" +) + +// FakeMachineHealthChecks implements MachineHealthCheckInterface +type FakeMachineHealthChecks struct { + Fake *FakeMachineremediationV1alpha1 + ns string +} + +var machinehealthchecksResource = schema.GroupVersionResource{Group: "machineremediation.kubevirt.io", Version: "v1alpha1", Resource: "machinehealthchecks"} + +var machinehealthchecksKind = schema.GroupVersionKind{Group: "machineremediation.kubevirt.io", Version: "v1alpha1", Kind: "MachineHealthCheck"} + +// Get takes name of the machineHealthCheck, and returns the corresponding machineHealthCheck object, and an error if there is any. +func (c *FakeMachineHealthChecks) Get(name string, options v1.GetOptions) (result *v1alpha1.MachineHealthCheck, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(machinehealthchecksResource, c.ns, name), &v1alpha1.MachineHealthCheck{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.MachineHealthCheck), err +} + +// List takes label and field selectors, and returns the list of MachineHealthChecks that match those selectors. +func (c *FakeMachineHealthChecks) List(opts v1.ListOptions) (result *v1alpha1.MachineHealthCheckList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(machinehealthchecksResource, machinehealthchecksKind, c.ns, opts), &v1alpha1.MachineHealthCheckList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1alpha1.MachineHealthCheckList{ListMeta: obj.(*v1alpha1.MachineHealthCheckList).ListMeta} + for _, item := range obj.(*v1alpha1.MachineHealthCheckList).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 machineHealthChecks. +func (c *FakeMachineHealthChecks) Watch(opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(machinehealthchecksResource, c.ns, opts)) + +} + +// Create takes the representation of a machineHealthCheck and creates it. Returns the server's representation of the machineHealthCheck, and an error, if there is any. +func (c *FakeMachineHealthChecks) Create(machineHealthCheck *v1alpha1.MachineHealthCheck) (result *v1alpha1.MachineHealthCheck, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(machinehealthchecksResource, c.ns, machineHealthCheck), &v1alpha1.MachineHealthCheck{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.MachineHealthCheck), err +} + +// Update takes the representation of a machineHealthCheck and updates it. Returns the server's representation of the machineHealthCheck, and an error, if there is any. +func (c *FakeMachineHealthChecks) Update(machineHealthCheck *v1alpha1.MachineHealthCheck) (result *v1alpha1.MachineHealthCheck, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(machinehealthchecksResource, c.ns, machineHealthCheck), &v1alpha1.MachineHealthCheck{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.MachineHealthCheck), 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 *FakeMachineHealthChecks) UpdateStatus(machineHealthCheck *v1alpha1.MachineHealthCheck) (*v1alpha1.MachineHealthCheck, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(machinehealthchecksResource, "status", c.ns, machineHealthCheck), &v1alpha1.MachineHealthCheck{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.MachineHealthCheck), err +} + +// Delete takes name of the machineHealthCheck and deletes it. Returns an error if one occurs. +func (c *FakeMachineHealthChecks) Delete(name string, options *v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteAction(machinehealthchecksResource, c.ns, name), &v1alpha1.MachineHealthCheck{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeMachineHealthChecks) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(machinehealthchecksResource, c.ns, listOptions) + + _, err := c.Fake.Invokes(action, &v1alpha1.MachineHealthCheckList{}) + return err +} + +// Patch applies the patch and returns the patched machineHealthCheck. +func (c *FakeMachineHealthChecks) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.MachineHealthCheck, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(machinehealthchecksResource, c.ns, name, pt, data, subresources...), &v1alpha1.MachineHealthCheck{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.MachineHealthCheck), err +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/fake/fake_machineremediation.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/fake/fake_machineremediation.go new file mode 100644 index 0000000000..221b715f3b --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/fake/fake_machineremediation.go @@ -0,0 +1,140 @@ +/* + * 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. + * + * Copyright 2019 Red Hat, Inc. + * + */ +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + schema "k8s.io/apimachinery/pkg/runtime/schema" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" + v1alpha1 "kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1" +) + +// FakeMachineRemediations implements MachineRemediationInterface +type FakeMachineRemediations struct { + Fake *FakeMachineremediationV1alpha1 + ns string +} + +var machineremediationsResource = schema.GroupVersionResource{Group: "machineremediation.kubevirt.io", Version: "v1alpha1", Resource: "machineremediations"} + +var machineremediationsKind = schema.GroupVersionKind{Group: "machineremediation.kubevirt.io", Version: "v1alpha1", Kind: "MachineRemediation"} + +// Get takes name of the machineRemediation, and returns the corresponding machineRemediation object, and an error if there is any. +func (c *FakeMachineRemediations) Get(name string, options v1.GetOptions) (result *v1alpha1.MachineRemediation, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(machineremediationsResource, c.ns, name), &v1alpha1.MachineRemediation{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.MachineRemediation), err +} + +// List takes label and field selectors, and returns the list of MachineRemediations that match those selectors. +func (c *FakeMachineRemediations) List(opts v1.ListOptions) (result *v1alpha1.MachineRemediationList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(machineremediationsResource, machineremediationsKind, c.ns, opts), &v1alpha1.MachineRemediationList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1alpha1.MachineRemediationList{ListMeta: obj.(*v1alpha1.MachineRemediationList).ListMeta} + for _, item := range obj.(*v1alpha1.MachineRemediationList).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 machineRemediations. +func (c *FakeMachineRemediations) Watch(opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(machineremediationsResource, c.ns, opts)) + +} + +// Create takes the representation of a machineRemediation and creates it. Returns the server's representation of the machineRemediation, and an error, if there is any. +func (c *FakeMachineRemediations) Create(machineRemediation *v1alpha1.MachineRemediation) (result *v1alpha1.MachineRemediation, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(machineremediationsResource, c.ns, machineRemediation), &v1alpha1.MachineRemediation{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.MachineRemediation), err +} + +// Update takes the representation of a machineRemediation and updates it. Returns the server's representation of the machineRemediation, and an error, if there is any. +func (c *FakeMachineRemediations) Update(machineRemediation *v1alpha1.MachineRemediation) (result *v1alpha1.MachineRemediation, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(machineremediationsResource, c.ns, machineRemediation), &v1alpha1.MachineRemediation{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.MachineRemediation), 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 *FakeMachineRemediations) UpdateStatus(machineRemediation *v1alpha1.MachineRemediation) (*v1alpha1.MachineRemediation, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(machineremediationsResource, "status", c.ns, machineRemediation), &v1alpha1.MachineRemediation{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.MachineRemediation), err +} + +// Delete takes name of the machineRemediation and deletes it. Returns an error if one occurs. +func (c *FakeMachineRemediations) Delete(name string, options *v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteAction(machineremediationsResource, c.ns, name), &v1alpha1.MachineRemediation{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeMachineRemediations) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(machineremediationsResource, c.ns, listOptions) + + _, err := c.Fake.Invokes(action, &v1alpha1.MachineRemediationList{}) + return err +} + +// Patch applies the patch and returns the patched machineRemediation. +func (c *FakeMachineRemediations) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.MachineRemediation, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(machineremediationsResource, c.ns, name, pt, data, subresources...), &v1alpha1.MachineRemediation{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.MachineRemediation), err +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/fake/fake_machineremediation_client.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/fake/fake_machineremediation_client.go new file mode 100644 index 0000000000..eeef34efd4 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/fake/fake_machineremediation_client.go @@ -0,0 +1,52 @@ +/* + * 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. + * + * Copyright 2019 Red Hat, Inc. + * + */ +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + rest "k8s.io/client-go/rest" + testing "k8s.io/client-go/testing" + v1alpha1 "kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1" +) + +type FakeMachineremediationV1alpha1 struct { + *testing.Fake +} + +func (c *FakeMachineremediationV1alpha1) MachineDisruptionBudgets(namespace string) v1alpha1.MachineDisruptionBudgetInterface { + return &FakeMachineDisruptionBudgets{c, namespace} +} + +func (c *FakeMachineremediationV1alpha1) MachineHealthChecks(namespace string) v1alpha1.MachineHealthCheckInterface { + return &FakeMachineHealthChecks{c, namespace} +} + +func (c *FakeMachineremediationV1alpha1) MachineRemediations(namespace string) v1alpha1.MachineRemediationInterface { + return &FakeMachineRemediations{c, namespace} +} + +func (c *FakeMachineremediationV1alpha1) MachineRemediationOperators(namespace string) v1alpha1.MachineRemediationOperatorInterface { + return &FakeMachineRemediationOperators{c, namespace} +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *FakeMachineremediationV1alpha1) RESTClient() rest.Interface { + var ret *rest.RESTClient + return ret +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/fake/fake_machineremediationoperator.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/fake/fake_machineremediationoperator.go new file mode 100644 index 0000000000..fa05a1a491 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/fake/fake_machineremediationoperator.go @@ -0,0 +1,140 @@ +/* + * 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. + * + * Copyright 2019 Red Hat, Inc. + * + */ +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + schema "k8s.io/apimachinery/pkg/runtime/schema" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" + v1alpha1 "kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1" +) + +// FakeMachineRemediationOperators implements MachineRemediationOperatorInterface +type FakeMachineRemediationOperators struct { + Fake *FakeMachineremediationV1alpha1 + ns string +} + +var machineremediationoperatorsResource = schema.GroupVersionResource{Group: "machineremediation.kubevirt.io", Version: "v1alpha1", Resource: "machineremediationoperators"} + +var machineremediationoperatorsKind = schema.GroupVersionKind{Group: "machineremediation.kubevirt.io", Version: "v1alpha1", Kind: "MachineRemediationOperator"} + +// Get takes name of the machineRemediationOperator, and returns the corresponding machineRemediationOperator object, and an error if there is any. +func (c *FakeMachineRemediationOperators) Get(name string, options v1.GetOptions) (result *v1alpha1.MachineRemediationOperator, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(machineremediationoperatorsResource, c.ns, name), &v1alpha1.MachineRemediationOperator{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.MachineRemediationOperator), err +} + +// List takes label and field selectors, and returns the list of MachineRemediationOperators that match those selectors. +func (c *FakeMachineRemediationOperators) List(opts v1.ListOptions) (result *v1alpha1.MachineRemediationOperatorList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(machineremediationoperatorsResource, machineremediationoperatorsKind, c.ns, opts), &v1alpha1.MachineRemediationOperatorList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1alpha1.MachineRemediationOperatorList{ListMeta: obj.(*v1alpha1.MachineRemediationOperatorList).ListMeta} + for _, item := range obj.(*v1alpha1.MachineRemediationOperatorList).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 machineRemediationOperators. +func (c *FakeMachineRemediationOperators) Watch(opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(machineremediationoperatorsResource, c.ns, opts)) + +} + +// Create takes the representation of a machineRemediationOperator and creates it. Returns the server's representation of the machineRemediationOperator, and an error, if there is any. +func (c *FakeMachineRemediationOperators) Create(machineRemediationOperator *v1alpha1.MachineRemediationOperator) (result *v1alpha1.MachineRemediationOperator, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(machineremediationoperatorsResource, c.ns, machineRemediationOperator), &v1alpha1.MachineRemediationOperator{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.MachineRemediationOperator), err +} + +// Update takes the representation of a machineRemediationOperator and updates it. Returns the server's representation of the machineRemediationOperator, and an error, if there is any. +func (c *FakeMachineRemediationOperators) Update(machineRemediationOperator *v1alpha1.MachineRemediationOperator) (result *v1alpha1.MachineRemediationOperator, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(machineremediationoperatorsResource, c.ns, machineRemediationOperator), &v1alpha1.MachineRemediationOperator{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.MachineRemediationOperator), 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 *FakeMachineRemediationOperators) UpdateStatus(machineRemediationOperator *v1alpha1.MachineRemediationOperator) (*v1alpha1.MachineRemediationOperator, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(machineremediationoperatorsResource, "status", c.ns, machineRemediationOperator), &v1alpha1.MachineRemediationOperator{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.MachineRemediationOperator), err +} + +// Delete takes name of the machineRemediationOperator and deletes it. Returns an error if one occurs. +func (c *FakeMachineRemediationOperators) Delete(name string, options *v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteAction(machineremediationoperatorsResource, c.ns, name), &v1alpha1.MachineRemediationOperator{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeMachineRemediationOperators) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(machineremediationoperatorsResource, c.ns, listOptions) + + _, err := c.Fake.Invokes(action, &v1alpha1.MachineRemediationOperatorList{}) + return err +} + +// Patch applies the patch and returns the patched machineRemediationOperator. +func (c *FakeMachineRemediationOperators) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.MachineRemediationOperator, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(machineremediationoperatorsResource, c.ns, name, pt, data, subresources...), &v1alpha1.MachineRemediationOperator{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.MachineRemediationOperator), err +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/generated_expansion.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/generated_expansion.go new file mode 100644 index 0000000000..4d99220a5e --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/generated_expansion.go @@ -0,0 +1,27 @@ +/* + * 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. + * + * Copyright 2019 Red Hat, Inc. + * + */ +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +type MachineDisruptionBudgetExpansion interface{} + +type MachineHealthCheckExpansion interface{} + +type MachineRemediationExpansion interface{} + +type MachineRemediationOperatorExpansion interface{} diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/machinedisruptionbudget.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/machinedisruptionbudget.go new file mode 100644 index 0000000000..36c70403a6 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/machinedisruptionbudget.go @@ -0,0 +1,191 @@ +/* + * 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. + * + * Copyright 2019 Red Hat, Inc. + * + */ +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "time" + + v1 "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" + v1alpha1 "kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1" + scheme "kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/scheme" +) + +// MachineDisruptionBudgetsGetter has a method to return a MachineDisruptionBudgetInterface. +// A group's client should implement this interface. +type MachineDisruptionBudgetsGetter interface { + MachineDisruptionBudgets(namespace string) MachineDisruptionBudgetInterface +} + +// MachineDisruptionBudgetInterface has methods to work with MachineDisruptionBudget resources. +type MachineDisruptionBudgetInterface interface { + Create(*v1alpha1.MachineDisruptionBudget) (*v1alpha1.MachineDisruptionBudget, error) + Update(*v1alpha1.MachineDisruptionBudget) (*v1alpha1.MachineDisruptionBudget, error) + UpdateStatus(*v1alpha1.MachineDisruptionBudget) (*v1alpha1.MachineDisruptionBudget, error) + Delete(name string, options *v1.DeleteOptions) error + DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error + Get(name string, options v1.GetOptions) (*v1alpha1.MachineDisruptionBudget, error) + List(opts v1.ListOptions) (*v1alpha1.MachineDisruptionBudgetList, error) + Watch(opts v1.ListOptions) (watch.Interface, error) + Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.MachineDisruptionBudget, err error) + MachineDisruptionBudgetExpansion +} + +// machineDisruptionBudgets implements MachineDisruptionBudgetInterface +type machineDisruptionBudgets struct { + client rest.Interface + ns string +} + +// newMachineDisruptionBudgets returns a MachineDisruptionBudgets +func newMachineDisruptionBudgets(c *MachineremediationV1alpha1Client, namespace string) *machineDisruptionBudgets { + return &machineDisruptionBudgets{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the machineDisruptionBudget, and returns the corresponding machineDisruptionBudget object, and an error if there is any. +func (c *machineDisruptionBudgets) Get(name string, options v1.GetOptions) (result *v1alpha1.MachineDisruptionBudget, err error) { + result = &v1alpha1.MachineDisruptionBudget{} + err = c.client.Get(). + Namespace(c.ns). + Resource("machinedisruptionbudgets"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of MachineDisruptionBudgets that match those selectors. +func (c *machineDisruptionBudgets) List(opts v1.ListOptions) (result *v1alpha1.MachineDisruptionBudgetList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha1.MachineDisruptionBudgetList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("machinedisruptionbudgets"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested machineDisruptionBudgets. +func (c *machineDisruptionBudgets) Watch(opts v1.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("machinedisruptionbudgets"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch() +} + +// Create takes the representation of a machineDisruptionBudget and creates it. Returns the server's representation of the machineDisruptionBudget, and an error, if there is any. +func (c *machineDisruptionBudgets) Create(machineDisruptionBudget *v1alpha1.MachineDisruptionBudget) (result *v1alpha1.MachineDisruptionBudget, err error) { + result = &v1alpha1.MachineDisruptionBudget{} + err = c.client.Post(). + Namespace(c.ns). + Resource("machinedisruptionbudgets"). + Body(machineDisruptionBudget). + Do(). + Into(result) + return +} + +// Update takes the representation of a machineDisruptionBudget and updates it. Returns the server's representation of the machineDisruptionBudget, and an error, if there is any. +func (c *machineDisruptionBudgets) Update(machineDisruptionBudget *v1alpha1.MachineDisruptionBudget) (result *v1alpha1.MachineDisruptionBudget, err error) { + result = &v1alpha1.MachineDisruptionBudget{} + err = c.client.Put(). + Namespace(c.ns). + Resource("machinedisruptionbudgets"). + Name(machineDisruptionBudget.Name). + Body(machineDisruptionBudget). + Do(). + 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 *machineDisruptionBudgets) UpdateStatus(machineDisruptionBudget *v1alpha1.MachineDisruptionBudget) (result *v1alpha1.MachineDisruptionBudget, err error) { + result = &v1alpha1.MachineDisruptionBudget{} + err = c.client.Put(). + Namespace(c.ns). + Resource("machinedisruptionbudgets"). + Name(machineDisruptionBudget.Name). + SubResource("status"). + Body(machineDisruptionBudget). + Do(). + Into(result) + return +} + +// Delete takes name of the machineDisruptionBudget and deletes it. Returns an error if one occurs. +func (c *machineDisruptionBudgets) Delete(name string, options *v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("machinedisruptionbudgets"). + Name(name). + Body(options). + Do(). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *machineDisruptionBudgets) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + var timeout time.Duration + if listOptions.TimeoutSeconds != nil { + timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("machinedisruptionbudgets"). + VersionedParams(&listOptions, scheme.ParameterCodec). + Timeout(timeout). + Body(options). + Do(). + Error() +} + +// Patch applies the patch and returns the patched machineDisruptionBudget. +func (c *machineDisruptionBudgets) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.MachineDisruptionBudget, err error) { + result = &v1alpha1.MachineDisruptionBudget{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("machinedisruptionbudgets"). + SubResource(subresources...). + Name(name). + Body(data). + Do(). + Into(result) + return +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/machinehealthcheck.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/machinehealthcheck.go new file mode 100644 index 0000000000..57503ce0c8 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/machinehealthcheck.go @@ -0,0 +1,191 @@ +/* + * 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. + * + * Copyright 2019 Red Hat, Inc. + * + */ +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "time" + + v1 "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" + v1alpha1 "kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1" + scheme "kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/scheme" +) + +// MachineHealthChecksGetter has a method to return a MachineHealthCheckInterface. +// A group's client should implement this interface. +type MachineHealthChecksGetter interface { + MachineHealthChecks(namespace string) MachineHealthCheckInterface +} + +// MachineHealthCheckInterface has methods to work with MachineHealthCheck resources. +type MachineHealthCheckInterface interface { + Create(*v1alpha1.MachineHealthCheck) (*v1alpha1.MachineHealthCheck, error) + Update(*v1alpha1.MachineHealthCheck) (*v1alpha1.MachineHealthCheck, error) + UpdateStatus(*v1alpha1.MachineHealthCheck) (*v1alpha1.MachineHealthCheck, error) + Delete(name string, options *v1.DeleteOptions) error + DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error + Get(name string, options v1.GetOptions) (*v1alpha1.MachineHealthCheck, error) + List(opts v1.ListOptions) (*v1alpha1.MachineHealthCheckList, error) + Watch(opts v1.ListOptions) (watch.Interface, error) + Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.MachineHealthCheck, err error) + MachineHealthCheckExpansion +} + +// machineHealthChecks implements MachineHealthCheckInterface +type machineHealthChecks struct { + client rest.Interface + ns string +} + +// newMachineHealthChecks returns a MachineHealthChecks +func newMachineHealthChecks(c *MachineremediationV1alpha1Client, namespace string) *machineHealthChecks { + return &machineHealthChecks{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the machineHealthCheck, and returns the corresponding machineHealthCheck object, and an error if there is any. +func (c *machineHealthChecks) Get(name string, options v1.GetOptions) (result *v1alpha1.MachineHealthCheck, err error) { + result = &v1alpha1.MachineHealthCheck{} + err = c.client.Get(). + Namespace(c.ns). + Resource("machinehealthchecks"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of MachineHealthChecks that match those selectors. +func (c *machineHealthChecks) List(opts v1.ListOptions) (result *v1alpha1.MachineHealthCheckList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha1.MachineHealthCheckList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("machinehealthchecks"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested machineHealthChecks. +func (c *machineHealthChecks) Watch(opts v1.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("machinehealthchecks"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch() +} + +// Create takes the representation of a machineHealthCheck and creates it. Returns the server's representation of the machineHealthCheck, and an error, if there is any. +func (c *machineHealthChecks) Create(machineHealthCheck *v1alpha1.MachineHealthCheck) (result *v1alpha1.MachineHealthCheck, err error) { + result = &v1alpha1.MachineHealthCheck{} + err = c.client.Post(). + Namespace(c.ns). + Resource("machinehealthchecks"). + Body(machineHealthCheck). + Do(). + Into(result) + return +} + +// Update takes the representation of a machineHealthCheck and updates it. Returns the server's representation of the machineHealthCheck, and an error, if there is any. +func (c *machineHealthChecks) Update(machineHealthCheck *v1alpha1.MachineHealthCheck) (result *v1alpha1.MachineHealthCheck, err error) { + result = &v1alpha1.MachineHealthCheck{} + err = c.client.Put(). + Namespace(c.ns). + Resource("machinehealthchecks"). + Name(machineHealthCheck.Name). + Body(machineHealthCheck). + Do(). + 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 *machineHealthChecks) UpdateStatus(machineHealthCheck *v1alpha1.MachineHealthCheck) (result *v1alpha1.MachineHealthCheck, err error) { + result = &v1alpha1.MachineHealthCheck{} + err = c.client.Put(). + Namespace(c.ns). + Resource("machinehealthchecks"). + Name(machineHealthCheck.Name). + SubResource("status"). + Body(machineHealthCheck). + Do(). + Into(result) + return +} + +// Delete takes name of the machineHealthCheck and deletes it. Returns an error if one occurs. +func (c *machineHealthChecks) Delete(name string, options *v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("machinehealthchecks"). + Name(name). + Body(options). + Do(). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *machineHealthChecks) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + var timeout time.Duration + if listOptions.TimeoutSeconds != nil { + timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("machinehealthchecks"). + VersionedParams(&listOptions, scheme.ParameterCodec). + Timeout(timeout). + Body(options). + Do(). + Error() +} + +// Patch applies the patch and returns the patched machineHealthCheck. +func (c *machineHealthChecks) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.MachineHealthCheck, err error) { + result = &v1alpha1.MachineHealthCheck{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("machinehealthchecks"). + SubResource(subresources...). + Name(name). + Body(data). + Do(). + Into(result) + return +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/machineremediation.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/machineremediation.go new file mode 100644 index 0000000000..9b262968d6 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/machineremediation.go @@ -0,0 +1,191 @@ +/* + * 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. + * + * Copyright 2019 Red Hat, Inc. + * + */ +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "time" + + v1 "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" + v1alpha1 "kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1" + scheme "kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/scheme" +) + +// MachineRemediationsGetter has a method to return a MachineRemediationInterface. +// A group's client should implement this interface. +type MachineRemediationsGetter interface { + MachineRemediations(namespace string) MachineRemediationInterface +} + +// MachineRemediationInterface has methods to work with MachineRemediation resources. +type MachineRemediationInterface interface { + Create(*v1alpha1.MachineRemediation) (*v1alpha1.MachineRemediation, error) + Update(*v1alpha1.MachineRemediation) (*v1alpha1.MachineRemediation, error) + UpdateStatus(*v1alpha1.MachineRemediation) (*v1alpha1.MachineRemediation, error) + Delete(name string, options *v1.DeleteOptions) error + DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error + Get(name string, options v1.GetOptions) (*v1alpha1.MachineRemediation, error) + List(opts v1.ListOptions) (*v1alpha1.MachineRemediationList, error) + Watch(opts v1.ListOptions) (watch.Interface, error) + Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.MachineRemediation, err error) + MachineRemediationExpansion +} + +// machineRemediations implements MachineRemediationInterface +type machineRemediations struct { + client rest.Interface + ns string +} + +// newMachineRemediations returns a MachineRemediations +func newMachineRemediations(c *MachineremediationV1alpha1Client, namespace string) *machineRemediations { + return &machineRemediations{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the machineRemediation, and returns the corresponding machineRemediation object, and an error if there is any. +func (c *machineRemediations) Get(name string, options v1.GetOptions) (result *v1alpha1.MachineRemediation, err error) { + result = &v1alpha1.MachineRemediation{} + err = c.client.Get(). + Namespace(c.ns). + Resource("machineremediations"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of MachineRemediations that match those selectors. +func (c *machineRemediations) List(opts v1.ListOptions) (result *v1alpha1.MachineRemediationList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha1.MachineRemediationList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("machineremediations"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested machineRemediations. +func (c *machineRemediations) Watch(opts v1.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("machineremediations"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch() +} + +// Create takes the representation of a machineRemediation and creates it. Returns the server's representation of the machineRemediation, and an error, if there is any. +func (c *machineRemediations) Create(machineRemediation *v1alpha1.MachineRemediation) (result *v1alpha1.MachineRemediation, err error) { + result = &v1alpha1.MachineRemediation{} + err = c.client.Post(). + Namespace(c.ns). + Resource("machineremediations"). + Body(machineRemediation). + Do(). + Into(result) + return +} + +// Update takes the representation of a machineRemediation and updates it. Returns the server's representation of the machineRemediation, and an error, if there is any. +func (c *machineRemediations) Update(machineRemediation *v1alpha1.MachineRemediation) (result *v1alpha1.MachineRemediation, err error) { + result = &v1alpha1.MachineRemediation{} + err = c.client.Put(). + Namespace(c.ns). + Resource("machineremediations"). + Name(machineRemediation.Name). + Body(machineRemediation). + Do(). + 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 *machineRemediations) UpdateStatus(machineRemediation *v1alpha1.MachineRemediation) (result *v1alpha1.MachineRemediation, err error) { + result = &v1alpha1.MachineRemediation{} + err = c.client.Put(). + Namespace(c.ns). + Resource("machineremediations"). + Name(machineRemediation.Name). + SubResource("status"). + Body(machineRemediation). + Do(). + Into(result) + return +} + +// Delete takes name of the machineRemediation and deletes it. Returns an error if one occurs. +func (c *machineRemediations) Delete(name string, options *v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("machineremediations"). + Name(name). + Body(options). + Do(). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *machineRemediations) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + var timeout time.Duration + if listOptions.TimeoutSeconds != nil { + timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("machineremediations"). + VersionedParams(&listOptions, scheme.ParameterCodec). + Timeout(timeout). + Body(options). + Do(). + Error() +} + +// Patch applies the patch and returns the patched machineRemediation. +func (c *machineRemediations) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.MachineRemediation, err error) { + result = &v1alpha1.MachineRemediation{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("machineremediations"). + SubResource(subresources...). + Name(name). + Body(data). + Do(). + Into(result) + return +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/machineremediation_client.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/machineremediation_client.go new file mode 100644 index 0000000000..0e817e66a4 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/machineremediation_client.go @@ -0,0 +1,105 @@ +/* + * 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. + * + * Copyright 2019 Red Hat, Inc. + * + */ +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + serializer "k8s.io/apimachinery/pkg/runtime/serializer" + rest "k8s.io/client-go/rest" + v1alpha1 "kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1" + "kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/scheme" +) + +type MachineremediationV1alpha1Interface interface { + RESTClient() rest.Interface + MachineDisruptionBudgetsGetter + MachineHealthChecksGetter + MachineRemediationsGetter + MachineRemediationOperatorsGetter +} + +// MachineremediationV1alpha1Client is used to interact with features provided by the machineremediation.kubevirt.io group. +type MachineremediationV1alpha1Client struct { + restClient rest.Interface +} + +func (c *MachineremediationV1alpha1Client) MachineDisruptionBudgets(namespace string) MachineDisruptionBudgetInterface { + return newMachineDisruptionBudgets(c, namespace) +} + +func (c *MachineremediationV1alpha1Client) MachineHealthChecks(namespace string) MachineHealthCheckInterface { + return newMachineHealthChecks(c, namespace) +} + +func (c *MachineremediationV1alpha1Client) MachineRemediations(namespace string) MachineRemediationInterface { + return newMachineRemediations(c, namespace) +} + +func (c *MachineremediationV1alpha1Client) MachineRemediationOperators(namespace string) MachineRemediationOperatorInterface { + return newMachineRemediationOperators(c, namespace) +} + +// NewForConfig creates a new MachineremediationV1alpha1Client for the given config. +func NewForConfig(c *rest.Config) (*MachineremediationV1alpha1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientFor(&config) + if err != nil { + return nil, err + } + return &MachineremediationV1alpha1Client{client}, nil +} + +// NewForConfigOrDie creates a new MachineremediationV1alpha1Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *MachineremediationV1alpha1Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new MachineremediationV1alpha1Client for the given RESTClient. +func New(c rest.Interface) *MachineremediationV1alpha1Client { + return &MachineremediationV1alpha1Client{c} +} + +func setConfigDefaults(config *rest.Config) error { + gv := v1alpha1.SchemeGroupVersion + config.GroupVersion = &gv + config.APIPath = "/apis" + config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: scheme.Codecs} + + 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 *MachineremediationV1alpha1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/machineremediationoperator.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/machineremediationoperator.go new file mode 100644 index 0000000000..3df3812749 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/typed/machineremediation/v1alpha1/machineremediationoperator.go @@ -0,0 +1,191 @@ +/* + * 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. + * + * Copyright 2019 Red Hat, Inc. + * + */ +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "time" + + v1 "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" + v1alpha1 "kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1" + scheme "kubevirt.io/machine-remediation-operator/pkg/client/clientset/versioned/scheme" +) + +// MachineRemediationOperatorsGetter has a method to return a MachineRemediationOperatorInterface. +// A group's client should implement this interface. +type MachineRemediationOperatorsGetter interface { + MachineRemediationOperators(namespace string) MachineRemediationOperatorInterface +} + +// MachineRemediationOperatorInterface has methods to work with MachineRemediationOperator resources. +type MachineRemediationOperatorInterface interface { + Create(*v1alpha1.MachineRemediationOperator) (*v1alpha1.MachineRemediationOperator, error) + Update(*v1alpha1.MachineRemediationOperator) (*v1alpha1.MachineRemediationOperator, error) + UpdateStatus(*v1alpha1.MachineRemediationOperator) (*v1alpha1.MachineRemediationOperator, error) + Delete(name string, options *v1.DeleteOptions) error + DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error + Get(name string, options v1.GetOptions) (*v1alpha1.MachineRemediationOperator, error) + List(opts v1.ListOptions) (*v1alpha1.MachineRemediationOperatorList, error) + Watch(opts v1.ListOptions) (watch.Interface, error) + Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.MachineRemediationOperator, err error) + MachineRemediationOperatorExpansion +} + +// machineRemediationOperators implements MachineRemediationOperatorInterface +type machineRemediationOperators struct { + client rest.Interface + ns string +} + +// newMachineRemediationOperators returns a MachineRemediationOperators +func newMachineRemediationOperators(c *MachineremediationV1alpha1Client, namespace string) *machineRemediationOperators { + return &machineRemediationOperators{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the machineRemediationOperator, and returns the corresponding machineRemediationOperator object, and an error if there is any. +func (c *machineRemediationOperators) Get(name string, options v1.GetOptions) (result *v1alpha1.MachineRemediationOperator, err error) { + result = &v1alpha1.MachineRemediationOperator{} + err = c.client.Get(). + Namespace(c.ns). + Resource("machineremediationoperators"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of MachineRemediationOperators that match those selectors. +func (c *machineRemediationOperators) List(opts v1.ListOptions) (result *v1alpha1.MachineRemediationOperatorList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha1.MachineRemediationOperatorList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("machineremediationoperators"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested machineRemediationOperators. +func (c *machineRemediationOperators) Watch(opts v1.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("machineremediationoperators"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch() +} + +// Create takes the representation of a machineRemediationOperator and creates it. Returns the server's representation of the machineRemediationOperator, and an error, if there is any. +func (c *machineRemediationOperators) Create(machineRemediationOperator *v1alpha1.MachineRemediationOperator) (result *v1alpha1.MachineRemediationOperator, err error) { + result = &v1alpha1.MachineRemediationOperator{} + err = c.client.Post(). + Namespace(c.ns). + Resource("machineremediationoperators"). + Body(machineRemediationOperator). + Do(). + Into(result) + return +} + +// Update takes the representation of a machineRemediationOperator and updates it. Returns the server's representation of the machineRemediationOperator, and an error, if there is any. +func (c *machineRemediationOperators) Update(machineRemediationOperator *v1alpha1.MachineRemediationOperator) (result *v1alpha1.MachineRemediationOperator, err error) { + result = &v1alpha1.MachineRemediationOperator{} + err = c.client.Put(). + Namespace(c.ns). + Resource("machineremediationoperators"). + Name(machineRemediationOperator.Name). + Body(machineRemediationOperator). + Do(). + 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 *machineRemediationOperators) UpdateStatus(machineRemediationOperator *v1alpha1.MachineRemediationOperator) (result *v1alpha1.MachineRemediationOperator, err error) { + result = &v1alpha1.MachineRemediationOperator{} + err = c.client.Put(). + Namespace(c.ns). + Resource("machineremediationoperators"). + Name(machineRemediationOperator.Name). + SubResource("status"). + Body(machineRemediationOperator). + Do(). + Into(result) + return +} + +// Delete takes name of the machineRemediationOperator and deletes it. Returns an error if one occurs. +func (c *machineRemediationOperators) Delete(name string, options *v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("machineremediationoperators"). + Name(name). + Body(options). + Do(). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *machineRemediationOperators) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + var timeout time.Duration + if listOptions.TimeoutSeconds != nil { + timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("machineremediationoperators"). + VersionedParams(&listOptions, scheme.ParameterCodec). + Timeout(timeout). + Body(options). + Do(). + Error() +} + +// Patch applies the patch and returns the patched machineRemediationOperator. +func (c *machineRemediationOperators) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.MachineRemediationOperator, err error) { + result = &v1alpha1.MachineRemediationOperator{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("machineremediationoperators"). + SubResource(subresources...). + Name(name). + Body(data). + Do(). + Into(result) + return +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/consts/consts.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/consts/consts.go new file mode 100644 index 0000000000..e629e9854b --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/consts/consts.go @@ -0,0 +1,16 @@ +package consts + +const ( + // AnnotationBareMetalHost contains the annotation key for bare metal host + AnnotationBareMetalHost = "metal3.io/BareMetalHost" + // AnnotationMachine contains the annotation key for machine + AnnotationMachine = "machine.openshift.io/machine" + // ControllerMachineDisruptionBudget contains the name of MachineDisruptionBudget controller + ControllerMachineDisruptionBudget = "machine-disruption-budget" + // ControllerMachineHealthCheck contains the name of MachineHealthCheck controller + ControllerMachineHealthCheck = "machine-health-check" + // ControllerMachineRemediation contains the name of achineRemediation controller + ControllerMachineRemediation = "machine-remediation" + // NamespaceOpenshiftMachineAPI contains namespace name for the machine-api componenets under the OpenShift cluster + NamespaceOpenshiftMachineAPI = "openshift-machine-api" +) diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/controllers/controller.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/controllers/controller.go new file mode 100644 index 0000000000..c102a557a1 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/controllers/controller.go @@ -0,0 +1,15 @@ +package controllers + +import ( + "sigs.k8s.io/controller-runtime/pkg/manager" +) + +// AddToManager adds all Controllers to the Manager +func AddToManager(m manager.Manager, opts manager.Options, fnList ...func(manager.Manager, manager.Options) error) error { + for _, f := range fnList { + if err := f(m, opts); err != nil { + return err + } + } + return nil +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/controllers/machinedisruptionbudget/machinedisruptionbudget_controller.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/controllers/machinedisruptionbudget/machinedisruptionbudget_controller.go new file mode 100644 index 0000000000..c2763c477d --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/controllers/machinedisruptionbudget/machinedisruptionbudget_controller.go @@ -0,0 +1,545 @@ +package disruption + +import ( + "context" + "fmt" + "time" + + "github.com/golang/glog" + + v1 "k8s.io/api/core/v1" + apiequality "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/tools/record" + "k8s.io/client-go/util/retry" + + mrv1 "kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1" + machineutil "kubevirt.io/machine-remediation-operator/pkg/utils/machines" + + mapiv1 "sigs.k8s.io/cluster-api/pkg/apis/machine/v1beta1" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + "sigs.k8s.io/controller-runtime/pkg/source" +) + +const ( + // DeletionTimeout sets maximum time from the moment a machine is added to DisruptedMachines in MDB.Status + // to the time when the machine is expected to be seen by MDB controller as having been marked for deletion. + // If the machine was not marked for deletion during that time it is assumed that it won't be deleted at + // all and the corresponding entry can be removed from mdb.Status.DisruptedMachines. It is assumed that + // machine/mdb apiserver to controller latency is relatively small (like 1-2sec) so the below value should + // be more than enough. + // If the controller is running on a different node it is important that the two nodes have synced + // clock (via ntp for example). Otherwise MachineDisruptionBudget controller may not provide enough + // protection against unwanted machine disruptions. + DeletionTimeout = 2 * time.Minute + // maxDisruptedMachinSize is the max size of MachineDisruptionBudgetStatus.DisruptedMachines. + // MachineHealthCheck will refuse to delete machine covered by the corresponding MDB + // if the size of the map exceeds this value. + maxDisruptedMachinSize = 50 +) + +// updateMDBRetry is the retry for a conflict where multiple clients +// are making changes to the same resource. +var updateMDBRetry = wait.Backoff{ + Steps: 20, + Duration: 500 * time.Millisecond, + Factor: 1.0, + Jitter: 0.1, +} + +// Add creates a new MachineDisruption Controller and adds it to the Manager. The Manager will set fields on the Controller +// and start it when the Manager is started. +func Add(mgr manager.Manager, opts manager.Options) error { + r := newReconciler(mgr, opts) + return add(mgr, r, r.machineToMachineDisruptionBudget) +} + +// newReconciler returns a new reconcile.Reconciler +func newReconciler(mgr manager.Manager, opts manager.Options) *ReconcileMachineDisruption { + return &ReconcileMachineDisruption{ + client: mgr.GetClient(), + recorder: mgr.GetEventRecorderFor("machine-disruption-controller"), + } +} + +// add adds a new Controller to mgr with r as the reconcile.Reconciler +func add(mgr manager.Manager, r reconcile.Reconciler, mapFn handler.ToRequestsFunc) error { + // Create a new controller + c, err := controller.New("MachineDisruption-controller", mgr, controller.Options{Reconciler: r}) + if err != nil { + return err + } + + if err = c.Watch(&source.Kind{Type: &mapiv1.Machine{}}, &handler.EnqueueRequestsFromMapFunc{ToRequests: mapFn}); err != nil { + return err + } + + return c.Watch(&source.Kind{Type: &mrv1.MachineDisruptionBudget{}}, &handler.EnqueueRequestForObject{}) +} + +var _ reconcile.Reconciler = &ReconcileMachineDisruption{} + +// ReconcileMachineDisruption reconciles a MachineDisruption object +type ReconcileMachineDisruption struct { + // This client, initialized using mgr.Client() above, is a split client + // that reads objects from the cache and writes to the apiserver + client client.Client + recorder record.EventRecorder +} + +// Reconcile reads that state of the cluster for MachineDisruptionBudget and machine objects and makes changes based on labels under +// MachineDisruptionBudget or machine objects +// Note: +// The Controller will requeue the Request to be processed again if the returned error is non-nil or +// Result.Requeue is true, otherwise upon completion it will remove the work from the queue. +func (r *ReconcileMachineDisruption) Reconcile(request reconcile.Request) (reconcile.Result, error) { + glog.V(4).Infof("Reconciling MachineDisruption triggered by %s/%s\n", request.Namespace, request.Name) + + // Get machine from request + mdb := &mrv1.MachineDisruptionBudget{} + err := r.client.Get(context.TODO(), request.NamespacedName, mdb) + if err != nil { + if errors.IsNotFound(err) { + // Request object not found, could have been deleted after reconcile request. + // Owned objects are automatically garbage collected. For additional cleanup logic use finalizers. + // Return and don't requeue + return reconcile.Result{}, nil + } + // Error reading the object - requeue the request. + return reconcile.Result{}, err + } + result, err := r.reconcile(mdb) + if err != nil { + glog.Errorf("Failed to reconcile mdb %s/%s: %v", mdb.Namespace, mdb.Name, err) + err = r.failSafe(mdb) + } + return result, err +} + +func (r *ReconcileMachineDisruption) reconcile(mdb *mrv1.MachineDisruptionBudget) (reconcile.Result, error) { + machines, err := r.getMachinesForMachineDisruptionBudget(mdb) + if err != nil { + r.recorder.Eventf(mdb, v1.EventTypeWarning, "NoMachines", "Failed to get machines: %v", err) + return reconcile.Result{}, err + } + + if len(machines) == 0 { + r.recorder.Eventf(mdb, v1.EventTypeNormal, "NoMachines", "No matching machines found") + } + + total, desiredHealthy := r.getTotalAndDesiredMachinesCount(mdb, machines) + + currentTime := time.Now() + disruptedMachines, recheckTime := r.buildDisruptedMachineMap(machines, mdb, currentTime) + + currentHealthy, err := r.countHealthyMachines(machines, disruptedMachines, currentTime) + if err != nil { + return reconcile.Result{}, err + } + + err = r.updateMachineDisruptionBudgetStatus(mdb, currentHealthy, desiredHealthy, total, disruptedMachines) + if err != nil { + return reconcile.Result{}, err + } + + if recheckTime != nil { + return reconcile.Result{Requeue: true, RequeueAfter: recheckTime.Sub(currentTime)}, nil + } + + return reconcile.Result{}, nil +} + +func (r *ReconcileMachineDisruption) getTotalAndDesiredMachinesCount(mdb *mrv1.MachineDisruptionBudget, machines []mapiv1.Machine) (total, desiredHealthy int32) { + total = r.getTotalMachinesCount(mdb, machines) + if mdb.Spec.MaxUnavailable != nil { + desiredHealthy = total - int32(*mdb.Spec.MaxUnavailable) + if desiredHealthy < 0 { + desiredHealthy = 0 + } + } else if mdb.Spec.MinAvailable != nil { + desiredHealthy = *mdb.Spec.MinAvailable + } + return +} + +// getTotalMachinesCount returns total number of machines that monitored by the MDB, if the machine has owner controller, +// it will get number of desired replicas from the controller and add it to the total number. +func (r *ReconcileMachineDisruption) getTotalMachinesCount(mdb *mrv1.MachineDisruptionBudget, machines []mapiv1.Machine) int32 { + // When the user specifies a fraction of machines that must be available, we + // use as the fraction's denominator + // SUM_{all c in C} scale(c) + // where C is the union of C_m1, C_m2, ..., C_mN + // and each C_mi is the set of controllers controlling the machine mi + + // A mapping from controllers to their scale. + controllerScale := map[types.UID]int32{} + + // 1. Find the controller for each machine. If any machine has 0 controllers, + // it will add map item with machine.UID as a key and 1 as a value. + // With ControllerRef, a machine can only have 1 controller. + for _, machine := range machines { + foundController := false + for _, finder := range r.finders() { + controllerNScale := finder(&machine) + if controllerNScale != nil { + if _, ok := controllerScale[controllerNScale.UID]; !ok { + controllerScale[controllerNScale.UID] = controllerNScale.scale + } + foundController = true + break + } + } + if !foundController { + controllerScale[machine.UID] = 1 + } + } + + // 2. Sum up all relevant machine scales to get the expected number + var total int32 + for _, count := range controllerScale { + total += count + } + return total +} + +type controllerAndScale struct { + types.UID + scale int32 +} + +// machineControllerFinder is a function type that maps a machine to a list of +// controllers and their scale. +type machineControllerFinder func(*mapiv1.Machine) *controllerAndScale + +var ( + controllerKindMachineSet = mapiv1.SchemeGroupVersion.WithKind("MachineSet") + controllerKindMachineDeployment = mapiv1.SchemeGroupVersion.WithKind("MachineDeployment") +) + +func (r *ReconcileMachineDisruption) finders() []machineControllerFinder { + return []machineControllerFinder{r.getMachineSetFinder, r.getMachineDeploymentFinder} +} + +func (r *ReconcileMachineDisruption) getMachineMachineSet(machine *mapiv1.Machine) *mapiv1.MachineSet { + controllerRef := metav1.GetControllerOf(machine) + if controllerRef == nil { + glog.Infof("machine %s does not have owner reference", machine.Name) + return nil + } + if controllerRef.Kind != controllerKindMachineSet.Kind { + // Skip MachineSet if the machine controlled by different controller + return nil + } + + machineSet := &mapiv1.MachineSet{} + key := client.ObjectKey{Namespace: machine.Namespace, Name: controllerRef.Name} + err := r.client.Get(context.TODO(), key, machineSet) + if err != nil { + glog.Infof("failed to get machine set object for machine %s", machine.Name) + return nil + } + + if machineSet.UID != controllerRef.UID { + glog.Infof("machine %s owner reference UID is different from machines set %s UID", machine.Name, machineSet.Name) + return nil + } + + return machineSet +} + +func (r *ReconcileMachineDisruption) getMachineSetFinder(machine *mapiv1.Machine) *controllerAndScale { + machineSet := r.getMachineMachineSet(machine) + if machineSet == nil { + return nil + } + + controllerRef := metav1.GetControllerOf(machineSet) + if controllerRef != nil && controllerRef.Kind == controllerKindMachineDeployment.Kind { + // Skip MachineSet if it's controlled by a Deployment. + return nil + } + return &controllerAndScale{machineSet.UID, *(machineSet.Spec.Replicas)} +} + +func (r *ReconcileMachineDisruption) getMachineDeploymentFinder(machine *mapiv1.Machine) *controllerAndScale { + machineSet := r.getMachineMachineSet(machine) + if machineSet == nil { + return nil + } + + controllerRef := metav1.GetControllerOf(machineSet) + if controllerRef == nil { + return nil + } + if controllerRef.Kind != controllerKindMachineDeployment.Kind { + return nil + } + machineDeployment := &mapiv1.MachineDeployment{} + key := client.ObjectKey{Namespace: machine.Namespace, Name: controllerRef.Name} + err := r.client.Get(context.TODO(), key, machineDeployment) + if err != nil { + // The only possible error is NotFound, which is ok here. + return nil + } + if machineDeployment.UID != controllerRef.UID { + return nil + } + return &controllerAndScale{machineDeployment.UID, *(machineDeployment.Spec.Replicas)} +} + +func (r *ReconcileMachineDisruption) countHealthyMachines(machines []mapiv1.Machine, disruptedMachines map[string]metav1.Time, currentTime time.Time) (int32, error) { + var currentHealthy int32 + + for _, machine := range machines { + // Machine is being deleted. + if machine.DeletionTimestamp != nil { + continue + } + // Machine is expected to be deleted soon. + if disruptionTime, found := disruptedMachines[machine.Name]; found && disruptionTime.Time.Add(DeletionTimeout).After(currentTime) { + continue + } + + healthy, err := machineutil.IsMachineHealthy(r.client, &machine) + if err != nil { + return currentHealthy, err + } + if healthy { + currentHealthy++ + } + } + return currentHealthy, nil +} + +func (r *ReconcileMachineDisruption) updateMachineDisruptionBudgetStatus( + mdb *mrv1.MachineDisruptionBudget, + currentHealthy, + desiredHealthy, + total int32, + disruptedMachines map[string]metav1.Time) error { + + // we add one because we do not want to respect disruption budget when expected and healthy are equal + disruptionsAllowed := currentHealthy - desiredHealthy + 1 + + // We require expectedCount to be > 0 so that MDBs which currently match no + // machines are in a safe state when their first machines appear but this controller + // has not updated their status yet. This isn't the only race, but it's a + // common one that's easy to detect. + if total <= 0 || disruptionsAllowed <= 0 { + disruptionsAllowed = 0 + } + + if mdb.Status.CurrentHealthy == currentHealthy && + mdb.Status.DesiredHealthy == desiredHealthy && + mdb.Status.Total == total && + mdb.Status.MachineDisruptionsAllowed == disruptionsAllowed && + apiequality.Semantic.DeepEqual(mdb.Status.DisruptedMachines, disruptedMachines) && + mdb.Status.ObservedGeneration == mdb.Generation { + return nil + } + + newMdb := mdb.DeepCopy() + newMdb.Status = mrv1.MachineDisruptionBudgetStatus{ + CurrentHealthy: currentHealthy, + DesiredHealthy: desiredHealthy, + Total: total, + MachineDisruptionsAllowed: disruptionsAllowed, + DisruptedMachines: disruptedMachines, + ObservedGeneration: mdb.Generation, + } + + return r.client.Status().Update(context.TODO(), newMdb) +} + +// failSafe is an attempt to at least update the MachineDisruptionsAllowed field to +// 0 if everything else has failed. This is one place we +// implement the "fail open" part of the design since if we manage to update +// this field correctly, we will prevent the deletion when it may be unsafe to do +func (r *ReconcileMachineDisruption) failSafe(mdb *mrv1.MachineDisruptionBudget) error { + newMdb := mdb.DeepCopy() + mdb.Status.MachineDisruptionsAllowed = 0 + return r.client.Status().Update(context.TODO(), newMdb) +} + +func (r *ReconcileMachineDisruption) getMachineDisruptionBudgetForMachine(machine *mapiv1.Machine) *mrv1.MachineDisruptionBudget { + // GetMachineMachineDisruptionBudgets returns an error only if no + // MachineDisruptionBudgets are found. We don't return that as an error to the + // caller. + mdbs, err := machineutil.GetMachineMachineDisruptionBudgets(r.client, machine) + if err != nil { + glog.V(4).Infof("No MachineDisruptionBudgets found for machine %v, MachineDisruptionBudget controller will avoid syncing.", machine.Name) + return nil + } + + if len(mdbs) == 0 { + glog.V(4).Infof("Could not find MachineDisruptionBudget for machine %s in namespace %s with labels: %v", machine.Name, machine.Namespace, machine.Labels) + return nil + } + + if len(mdbs) > 1 { + msg := fmt.Sprintf("Machine %q/%q matches multiple MachineDisruptionBudgets. Chose %q arbitrarily.", machine.Namespace, machine.Name, mdbs[0].Name) + glog.Warning(msg) + r.recorder.Event(machine, v1.EventTypeWarning, "MultipleMachineDisruptionBudgets", msg) + } + return mdbs[0] +} + +// This function returns machines using the MachineDisruptionBudget object. +func (r *ReconcileMachineDisruption) getMachinesForMachineDisruptionBudget(mdb *mrv1.MachineDisruptionBudget) ([]mapiv1.Machine, error) { + sel, err := metav1.LabelSelectorAsSelector(mdb.Spec.Selector) + if err != nil { + return nil, err + } + if sel.Empty() { + return nil, nil + } + + machines := &mapiv1.MachineList{} + listOptions := &client.ListOptions{ + Namespace: mdb.Namespace, + LabelSelector: sel, + } + err = r.client.List(context.TODO(), machines, client.UseListOptions(listOptions)) + if err != nil { + return nil, err + } + return machines.Items, nil +} + +// Builds new MachineDisruption map, possibly removing items that refer to non-existing, already deleted +// or not-deleted at all items. Also returns an information when this check should be repeated. +func (r *ReconcileMachineDisruption) buildDisruptedMachineMap(machines []mapiv1.Machine, mdb *mrv1.MachineDisruptionBudget, currentTime time.Time) (map[string]metav1.Time, *time.Time) { + disruptedMachines := mdb.Status.DisruptedMachines + result := make(map[string]metav1.Time) + var recheckTime *time.Time + + if disruptedMachines == nil || len(disruptedMachines) == 0 { + return result, recheckTime + } + for _, machine := range machines { + if machine.DeletionTimestamp != nil { + // Already being deleted. + continue + } + disruptionTime, found := disruptedMachines[machine.Name] + if !found { + // Machine not on the list. + continue + } + expectedDeletion := disruptionTime.Time.Add(DeletionTimeout) + if expectedDeletion.Before(currentTime) { + glog.V(1).Infof("Machine %s/%s was expected to be deleted at %s but it wasn't, updating mdb %s/%s", + machine.Namespace, machine.Name, disruptionTime.String(), mdb.Namespace, mdb.Name) + r.recorder.Eventf(&machine, v1.EventTypeWarning, "NotDeleted", "Machine was expected by MDB %s/%s to be deleted but it wasn't", + mdb.Namespace, mdb.Namespace) + } else { + if recheckTime == nil || expectedDeletion.Before(*recheckTime) { + recheckTime = &expectedDeletion + } + result[machine.Name] = disruptionTime + } + } + return result, recheckTime +} + +func (r *ReconcileMachineDisruption) machineToMachineDisruptionBudget(o handler.MapObject) []reconcile.Request { + machine := &mapiv1.Machine{} + key := client.ObjectKey{Namespace: o.Meta.GetNamespace(), Name: o.Meta.GetName()} + if err := r.client.Get(context.TODO(), key, machine); err != nil { + glog.V(4).Infof("Unable to retrieve Machine %v from store, uses a dummy machine to get MDB object: %v", key, err) + machine.Name = o.Meta.GetName() + machine.Namespace = o.Meta.GetNamespace() + machine.Labels = o.Meta.GetLabels() + } + + mdb := r.getMachineDisruptionBudgetForMachine(machine) + if mdb == nil { + glog.Errorf("Unable to find MachineDisruptionBudget for machine %s", machine.Name) + return nil + } + + name := client.ObjectKey{Namespace: mdb.Namespace, Name: mdb.Name} + return []reconcile.Request{{NamespacedName: name}} +} + +// isMachineDisruptionAllowed returns true if the provided MachineDisruptionBudget allows any disruption +func isMachineDisruptionAllowed(mdb *mrv1.MachineDisruptionBudget, maxDisruptedMachinSize int) bool { + if mdb.Status.ObservedGeneration < mdb.Generation { + glog.Warningf("The machine disruption budget %s is still being processed by the server", mdb.Name) + return false + } + if mdb.Status.MachineDisruptionsAllowed < 0 { + glog.Warningf("The machine disruption budget %s MachineDisruptionsAllowed is negative", mdb.Name) + return false + } + if len(mdb.Status.DisruptedMachines) > maxDisruptedMachinSize { + glog.Warningf("The machine disruption budget %s DisruptedMachines map too big - too many deletions not confirmed by MDB controller", mdb.Name) + return false + } + if mdb.Status.MachineDisruptionsAllowed == 0 { + glog.Warningf("Cannot remediate machine as it would violate the machine's disruption budget %s", mdb.Name) + return false + } + + return true +} + +func decrementMachineDisruptionsAllowed(c client.Client, machineName string, mdb *mrv1.MachineDisruptionBudget) error { + if mdb.Status.DisruptedMachines == nil { + mdb.Status.DisruptedMachines = make(map[string]metav1.Time) + } + + if _, exists := mdb.Status.DisruptedMachines[machineName]; exists { + return nil + } + + mdb.Status.MachineDisruptionsAllowed-- + + // MachineHealthCheck controller needs to inform the MDB controller that it is about to remediate a machine + // so it should not consider it as available in calculations when updating MachineDisruptions allowed. + // If the machine is not remediated within a reasonable time limit MDB controller will assume that it won't + // be remediated at all and remove it from DisruptedMachines map. + mdb.Status.DisruptedMachines[machineName] = metav1.Time{Time: time.Now()} + return c.Update(context.TODO(), mdb) +} + +// RetryDecrementMachineDisruptionsAllowed validates if the disruption is allowed, when it allowed it will decrement +// MDB MachineDisruptionsAllowed parameter and update the status of the MDB, in case when update failed +// on the conflict it will try again with the backoff +func RetryDecrementMachineDisruptionsAllowed(c client.Client, machine *mapiv1.Machine) error { + var mdb *mrv1.MachineDisruptionBudget + err := retry.RetryOnConflict(updateMDBRetry, func() error { + mdbs, err := machineutil.GetMachineMachineDisruptionBudgets(c, machine) + if err != nil { + return err + } + + if len(mdbs) > 1 { + return fmt.Errorf("machine %q has more than one MachineDisruptionBudget, which is not supported", machine.Name) + } + + if len(mdbs) == 1 { + mdb = mdbs[0] + + if !isMachineDisruptionAllowed(mdb, maxDisruptedMachinSize) { + return fmt.Errorf("machine disruption is not allowed") + } + + return decrementMachineDisruptionsAllowed(c, machine.Name, mdb) + } + return nil + }) + + if err == wait.ErrWaitTimeout { + err = fmt.Errorf("couldn't update MachineDisruptionBudget %q due to conflicts", mdb.Name) + } + + return err +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/controllers/machinehealthcheck/machinehealthcheck_controller.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/controllers/machinehealthcheck/machinehealthcheck_controller.go new file mode 100644 index 0000000000..0bf6a98704 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/controllers/machinehealthcheck/machinehealthcheck_controller.go @@ -0,0 +1,462 @@ +package machinehealthcheck + +import ( + "context" + golangerrors "errors" + "fmt" + "time" + + "github.com/golang/glog" + + 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" + "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/tools/cache" + + mrv1 "kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1" + disruption "kubevirt.io/machine-remediation-operator/pkg/controllers/machinedisruptionbudget" + "kubevirt.io/machine-remediation-operator/pkg/utils/conditions" + + mapiv1 "sigs.k8s.io/cluster-api/pkg/apis/machine/v1beta1" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + "sigs.k8s.io/controller-runtime/pkg/source" +) + +const ( + machineAnnotationKey = "machine.openshift.io/machine" + ownerControllerKind = "MachineSet" + disableRemediationAnotationKey = "healthchecking.openshift.io/disabled" +) + +var _ reconcile.Reconciler = &ReconcileMachineHealthCheck{} + +// Add creates a new MachineHealthCheck Controller and adds it to the Manager. The Manager will set fields on the Controller +// and start it when the Manager is started. +func Add(mgr manager.Manager, opts manager.Options) error { + r := newReconciler(mgr, opts) + return add(mgr, r, r.nodeRequestsFromMachineHealthCheck) +} + +// newReconciler returns a new reconcile.Reconciler +func newReconciler(mgr manager.Manager, opts manager.Options) *ReconcileMachineHealthCheck { + return &ReconcileMachineHealthCheck{ + client: mgr.GetClient(), + namespace: opts.Namespace, + } +} + +// add adds a new Controller to mgr with r as the reconcile.Reconciler +func add(mgr manager.Manager, r reconcile.Reconciler, mapFn handler.ToRequestsFunc) error { + // Create a new controller + c, err := controller.New("machinehealthcheck-controller", mgr, controller.Options{Reconciler: r}) + if err != nil { + return err + } + + // Watch MachineHealthChecks and enqueue reconcile.Request for the backed nodes. + // This is useful to trigger remediation when a machineHealCheck is created against + // a node which is already unhealthy and is not able to receive status updates. + err = c.Watch(&source.Kind{Type: &mrv1.MachineHealthCheck{}}, &handler.EnqueueRequestsFromMapFunc{ToRequests: mapFn}) + if err != nil { + return err + } + + return c.Watch(&source.Kind{Type: &corev1.Node{}}, &handler.EnqueueRequestForObject{}) +} + +func (r *ReconcileMachineHealthCheck) nodeRequestsFromMachineHealthCheck(o handler.MapObject) []reconcile.Request { + glog.V(3).Infof("Watched machineHealthCheck event, finding nodes to reconcile.Request...") + key := client.ObjectKey{ + Namespace: o.Meta.GetNamespace(), + Name: o.Meta.GetName(), + } + mhc := &mrv1.MachineHealthCheck{} + if err := r.client.Get(context.Background(), key, mhc); err != nil { + glog.Errorf("No-op: Unable to retrieve mhc %s/%s from store: %v", o.Meta.GetNamespace(), o.Meta.GetName(), err) + return nil + } + + if mhc.DeletionTimestamp != nil { + glog.V(3).Infof("No-op: mhc %q is being deleted", o.Meta.GetName()) + return nil + } + + // get nodes covered by then mhc + nodeNames, err := r.getNodeNamesForMHC(mhc) + if err != nil { + glog.Errorf("No-op: failed to get nodes for mhc %q", o.Meta.GetName()) + return nil + } + + if nodeNames != nil { + var requests []reconcile.Request + for _, nodeName := range nodeNames { + // convert to namespacedName to satisfy type Request struct + nodeNamespacedName := client.ObjectKey{Name: string(nodeName)} + requests = append(requests, reconcile.Request{NamespacedName: nodeNamespacedName}) + } + return requests + } + return nil +} + +func (r *ReconcileMachineHealthCheck) getNodeNamesForMHC(mhc *mrv1.MachineHealthCheck) ([]types.NodeName, error) { + machineList := &mapiv1.MachineList{} + selector, err := metav1.LabelSelectorAsSelector(&mhc.Spec.Selector) + if err != nil { + return nil, fmt.Errorf("failed to build selector") + } + options := &client.ListOptions{ + Namespace: mhc.Namespace, + LabelSelector: selector, + } + + if err := r.client.List(context.Background(), machineList, client.UseListOptions(options)); err != nil { + return nil, fmt.Errorf("failed to list machines: %v", err) + } + + if len(machineList.Items) < 1 { + return nil, nil + } + + var nodeNames []types.NodeName + for _, machine := range machineList.Items { + if machine.Status.NodeRef != nil { + nodeNames = append(nodeNames, types.NodeName(machine.Status.NodeRef.Name)) + } + } + if len(nodeNames) < 1 { + return nil, nil + } + return nodeNames, nil +} + +// ReconcileMachineHealthCheck reconciles a MachineHealthCheck object +type ReconcileMachineHealthCheck struct { + // This client, initialized using mgr.Client() above, is a split client + // that reads objects from the cache and writes to the apiserver + client client.Client + namespace string +} + +// Reconcile reads that state of the cluster for MachineHealthCheck, machine and nodes objects and makes changes based on the state read +// and what is in the MachineHealthCheck.Spec +// Note: +// The Controller will requeue the Request to be processed again if the returned error is non-nil or +// Result.Requeue is true, otherwise upon completion it will remove the work from the queue. +func (r *ReconcileMachineHealthCheck) Reconcile(request reconcile.Request) (reconcile.Result, error) { + glog.Infof("Reconciling MachineHealthCheck triggered by %s/%s\n", request.Namespace, request.Name) + + // Get node from request + node := &corev1.Node{} + err := r.client.Get(context.TODO(), request.NamespacedName, node) + if err != nil { + if errors.IsNotFound(err) { + // Request object not found, could have been deleted after reconcile request. + // Owned objects are automatically garbage collected. For additional cleanup logic use finalizers. + // Return and don't requeue + return reconcile.Result{}, nil + } + // Error reading the object - requeue the request. + return reconcile.Result{}, err + } + + machineKey, ok := node.Annotations[machineAnnotationKey] + if !ok { + glog.Warningf("No machine annotation for node %s", node.Name) + return reconcile.Result{}, nil + } + + glog.Infof("Node %s is annotated with machine %s", node.Name, machineKey) + machine := &mapiv1.Machine{} + namespace, machineName, err := cache.SplitMetaNamespaceKey(machineKey) + if err != nil { + return reconcile.Result{}, err + } + key := &types.NamespacedName{ + Namespace: namespace, + Name: machineName, + } + err = r.client.Get(context.TODO(), *key, machine) + if err != nil { + if errors.IsNotFound(err) { + glog.Warningf("machine %s not found", machineKey) + // Request object not found, could have been deleted after reconcile request. + // Owned objects are automatically garbage collected. For additional cleanup logic use finalizers. + // Return and don't requeue + return reconcile.Result{}, nil + } + // Error reading the object - requeue the request. + glog.Errorf("error getting machine %s. Error: %v. Requeuing...", machineKey, err) + return reconcile.Result{}, err + } + + if hasRemediationDisabledAnnotation(*machine) { + glog.Infof("Machine %q has a matching %s annotation set to , remediation is skipped.", machine.Name, disableRemediationAnotationKey) + return reconcile.Result{}, nil + } + + // If the current machine matches any existing MachineHealthCheck CRD + allMachineHealthChecks := &mrv1.MachineHealthCheckList{} + err = r.client.List(context.Background(), allMachineHealthChecks) + if err != nil { + glog.Errorf("failed to list MachineHealthChecks, %v", err) + return reconcile.Result{}, err + } + + for _, hc := range allMachineHealthChecks.Items { + + if hasMatchingLabels(&hc, machine) { + glog.V(4).Infof("Machine %s has a matching machineHealthCheck: %s", machineKey, hc.Name) + return remediate(r, hc.Spec.RemediationStrategy, machine) + } + } + + glog.Infof("Machine %s has no MachineHealthCheck associated", machineName) + return reconcile.Result{}, nil +} + +// This is set so the fake client can be used for unit test. See: +// https://github.com/kubernetes-sigs/controller-runtime/issues/168 +func getMachineHealthCheckListOptions() *client.ListOptions { + return &client.ListOptions{ + Raw: &metav1.ListOptions{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "healthchecking.openshift.io/v1alpha1", + Kind: "MachineHealthCheck", + }, + }, + } +} + +func remediate(r *ReconcileMachineHealthCheck, remediationStrategy *mrv1.RemediationStrategyType, machine *mapiv1.Machine) (reconcile.Result, error) { + glog.Infof("Initialising remediation logic for machine %s", machine.Name) + if !hasMachineSetOwner(machine) && !isMaster(machine, r.client) { + glog.Infof("Machine %s has no machineSet controller owner, skipping remediation", machine.Name) + return reconcile.Result{}, nil + } + + node, err := getNodeFromMachine(machine, r.client) + if err != nil { + if errors.IsNotFound(err) { + glog.Warningf("Node %s not found for machine %s", node.Name, machine.Name) + return reconcile.Result{}, nil + } + // Error reading the object - requeue the request. + return reconcile.Result{}, err + } + + cmUnhealtyConditions, err := conditions.GetUnhealthyConditionsConfigMap(r.client, r.namespace) + if err != nil { + return reconcile.Result{}, err + } + + nodeUnhealthyConditions, err := conditions.GetNodeUnhealthyConditions(node, cmUnhealtyConditions) + if err != nil { + return reconcile.Result{}, err + } + + var result *reconcile.Result + var minimalConditionTimeout time.Duration + minimalConditionTimeout = 0 + for _, c := range nodeUnhealthyConditions { + nodeCondition := conditions.GetNodeCondition(node, c.Name) + // skip when current node condition is different from the one reported in the config map + if nodeCondition == nil || !isConditionsStatusesEqual(nodeCondition, &c) { + continue + } + + conditionTimeout, err := time.ParseDuration(c.Timeout) + if err != nil { + return reconcile.Result{}, err + } + + // apply remediation logic, if at least one condition last more than specified timeout + // specific remediation logic goes here + if unhealthyForTooLong(nodeCondition, conditionTimeout) { + // do not fail immediatlty, but try again if the method fails because of the update conflict + if err = disruption.RetryDecrementMachineDisruptionsAllowed(r.client, machine); err != nil { + // if the error appears here it means that machine healthcheck operation restricted by machine + // disruption budget, in this case we want to re-try after one minute + glog.Warning(err) + return reconcile.Result{Requeue: true, RequeueAfter: time.Minute}, nil + } + + if remediationStrategy != nil && *remediationStrategy == mrv1.RemediationStrategyTypeReboot { + return r.remediationStrategyReboot(machine, node) + } + + if isMaster(machine, r.client) { + glog.Infof("The machine %s is a master node, skipping remediation", machine.Name) + return reconcile.Result{}, nil + } + glog.Infof("Machine %s has been unhealthy for too long, deleting", machine.Name) + if err := r.client.Delete(context.TODO(), machine); err != nil { + glog.Errorf("Failed to delete machine %s, requeuing referenced node", machine.Name) + return reconcile.Result{}, err + } + return reconcile.Result{}, nil + } + + now := time.Now() + durationUnhealthy := now.Sub(nodeCondition.LastTransitionTime.Time) + glog.Warningf( + "Machine %s has unhealthy node %s with the condition %s and the timeout %s for %s. Requeuing...", + machine.Name, + node.Name, + nodeCondition.Type, + c.Timeout, + durationUnhealthy.String(), + ) + + // calculate the duration until the node will be unhealthy for too long + // and re-queue after with this timeout, add one second just to be sure + // that we will not enter this loop again before the node unhealthy for too long + unhealthyTooLongTimeout := conditionTimeout - durationUnhealthy + time.Second + // be sure that we will use timeout with the minimal value for the reconcile.Result + if minimalConditionTimeout == 0 || minimalConditionTimeout > unhealthyTooLongTimeout { + minimalConditionTimeout = unhealthyTooLongTimeout + } + result = &reconcile.Result{Requeue: true, RequeueAfter: minimalConditionTimeout} + } + + // requeue + if result != nil { + return *result, nil + } + + glog.Infof("No remediaton action was taken. Machine %s with node %v is healthy", machine.Name, node.Name) + return reconcile.Result{}, nil +} + +func (r *ReconcileMachineHealthCheck) remediationStrategyReboot(machine *mapiv1.Machine, node *corev1.Node) (reconcile.Result, error) { + rebootInProgress, err := isRebootInProgress(r.client, machine.Name) + if err != nil { + return reconcile.Result{}, err + } + + // reboot already in progress, stop reconcile + if rebootInProgress { + return reconcile.Result{}, nil + } + + mr := &mrv1.MachineRemediation{ + ObjectMeta: metav1.ObjectMeta{ + GenerateName: "remediation-", + Namespace: machine.Namespace, + }, + Spec: mrv1.MachineRemediationSpec{ + MachineName: machine.Name, + Type: mrv1.RemediationTypeReboot, + }, + } + + glog.Infof("Machine %s has been unhealthy for too long, creating machine remediation", machine.Name) + if err = r.client.Create(context.TODO(), mr); err != nil { + return reconcile.Result{}, err + } + return reconcile.Result{}, nil +} + +func isConditionsStatusesEqual(cond *corev1.NodeCondition, unhealthyCond *conditions.UnhealthyCondition) bool { + return cond.Status == unhealthyCond.Status +} + +func getNodeFromMachine(machine *mapiv1.Machine, client client.Client) (*corev1.Node, error) { + if machine.Status.NodeRef == nil { + glog.Errorf("node NodeRef not found in machine %s", machine.Name) + return nil, golangerrors.New("node NodeRef not found in machine") + } + node := &corev1.Node{} + nodeKey := types.NamespacedName{ + Namespace: machine.Status.NodeRef.Namespace, + Name: machine.Status.NodeRef.Name, + } + err := client.Get(context.TODO(), nodeKey, node) + return node, err +} + +func unhealthyForTooLong(nodeCondition *corev1.NodeCondition, timeout time.Duration) bool { + now := time.Now() + if nodeCondition.LastTransitionTime.Add(timeout).Before(now) { + return true + } + return false +} + +func hasMachineSetOwner(machine *mapiv1.Machine) bool { + ownerRefs := machine.ObjectMeta.GetOwnerReferences() + for _, or := range ownerRefs { + if or.Kind == ownerControllerKind { + return true + } + } + return false +} + +func hasRemediationDisabledAnnotation(machine mapiv1.Machine) bool { + skipRemediation, ok := machine.Annotations[disableRemediationAnotationKey] + if !ok { + return false + } + return skipRemediation == "true" +} + +func hasMatchingLabels(machineHealthCheck *mrv1.MachineHealthCheck, machine *mapiv1.Machine) bool { + selector, err := metav1.LabelSelectorAsSelector(&machineHealthCheck.Spec.Selector) + if err != nil { + glog.Warningf("unable to convert selector: %v", err) + return false + } + // If a deployment with a nil or empty selector creeps in, it should match nothing, not everything. + if selector.Empty() { + glog.V(2).Infof("%v machineHealthCheck has empty selector", machineHealthCheck.Name) + return false + } + if !selector.Matches(labels.Set(machine.Labels)) { + glog.V(4).Infof("%v machine has mismatched labels", machine.Name) + return false + } + return true +} + +func isMaster(machine *mapiv1.Machine, client client.Client) bool { + masterLabels := []string{ + "node-role.kubernetes.io/master", + } + + node, err := getNodeFromMachine(machine, client) + if err != nil { + glog.Warningf("Couldn't get node for machine %s", machine.Name) + return false + } + nodeLabels := labels.Set(node.Labels) + for _, masterLabel := range masterLabels { + if nodeLabels.Has(masterLabel) { + return true + } + } + return false +} + +func isRebootInProgress(c client.Client, machineName string) (bool, error) { + machineRemediations := &mrv1.MachineRemediationList{} + if err := c.List(context.TODO(), machineRemediations); err != nil { + return false, err + } + + for _, mr := range machineRemediations.Items { + if mr.Spec.MachineName == machineName { + if mr.Status.EndTime != nil { + return true, nil + } + } + } + return false, nil +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/controllers/machineremediation/machineremediation_controller.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/controllers/machineremediation/machineremediation_controller.go new file mode 100644 index 0000000000..9717b36f15 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/controllers/machineremediation/machineremediation_controller.go @@ -0,0 +1,125 @@ +package machineremediation + +import ( + "context" + "time" + + "github.com/golang/glog" + + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + mrv1 "kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1" + + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + "sigs.k8s.io/controller-runtime/pkg/source" +) + +var _ reconcile.Reconciler = &ReconcileMachineRemediation{} + +// ReconcileMachineRemediation reconciles a MachineRemediation object +type ReconcileMachineRemediation struct { + // This client, initialized using mgr.Client() above, is a split client + // that reads objects from the cache and writes to the apiserver + client client.Client + remediator Remediator + namespace string +} + +// AddWithRemediator creates a new MachineRemediation Controller with remediator and adds it to the Manager. +// The Manager will set fields on the Controller and start it when the Manager is started. +func AddWithRemediator(mgr manager.Manager, remediator Remediator, opts manager.Options) error { + r, err := newReconciler(mgr, remediator, opts) + if err != nil { + return err + } + return add(mgr, r) +} + +func newReconciler(mgr manager.Manager, remediator Remediator, opts manager.Options) (reconcile.Reconciler, error) { + return &ReconcileMachineRemediation{ + client: mgr.GetClient(), + remediator: remediator, + namespace: opts.Namespace, + }, nil +} + +// add adds a new Controller to mgr with r as the reconcile.Reconciler +func add(mgr manager.Manager, r reconcile.Reconciler) error { + // Create a new controller + c, err := controller.New("machineremediation-controller", mgr, controller.Options{Reconciler: r}) + if err != nil { + return err + } + + return c.Watch(&source.Kind{Type: &mrv1.MachineRemediation{}}, &handler.EnqueueRequestForObject{}) +} + +// Reconcile monitors MachineRemediation and apply the remediation strategy in the case when the +// MachineRemediation was created +// Note: +// The Controller will requeue the Request to be processed again if the returned error is non-nil or +// Result.Requeue is true, otherwise upon completion it will remove the work from the queue. +func (r *ReconcileMachineRemediation) Reconcile(request reconcile.Request) (reconcile.Result, error) { + glog.V(4).Infof("Reconciling MachineRemediation triggered by %s/%s\n", request.Namespace, request.Name) + + // Get MachineRemediation from request + mr := &mrv1.MachineRemediation{} + err := r.client.Get(context.TODO(), request.NamespacedName, mr) + if err != nil { + if errors.IsNotFound(err) { + // Request object not found, could have been deleted after reconcile request. + // Owned objects are automatically garbage collected. For additional cleanup logic use finalizers. + // Return and don't requeue + return reconcile.Result{}, nil + } + // Error reading the object - requeue the request. + return reconcile.Result{}, err + } + + // we do not want to do anything on delete objects + if mr.DeletionTimestamp != nil { + return reconcile.Result{}, nil + } + + if mr.Status.State == "" { + mrCopy := mr.DeepCopy() + mrCopy.Status = mrv1.MachineRemediationStatus{ + State: mrv1.RemediationStateStarted, + Reason: "Machine remediation started", + StartTime: &metav1.Time{Time: time.Now()}, + } + if err := r.client.Status().Update(context.TODO(), mrCopy); err != nil { + glog.Errorf("failed to update MR %q status: %v", mr.Name, err) + return reconcile.Result{}, err + } + } + + switch mr.Spec.Type { + case mrv1.RemediationTypeReboot: + glog.V(4).Infof("Run remediation reboot acion for MachineRemediation %s", mr.Name) + if err := r.remediator.Reboot(context.TODO(), mr); err != nil { + glog.Errorf("Remediation reboot acion for MachineRemediation %s failed with error: %v", mr.Name, err) + return reconcile.Result{}, err + } + case mrv1.RemediationTypeRecreate: + glog.V(4).Infof("Run remediation recreate acion for MachineRemediation %s", mr.Name) + if err := r.remediator.Recreate(context.TODO(), mr); err != nil { + glog.Errorf("Remediation recreate acion for MachineRemediation %s failed with error: %v", mr.Name, err) + return reconcile.Result{}, err + } + } + + switch mr.Status.State { + // we want to stop reconcile the object once it reaches Succeeded or Failed state + case mrv1.RemediationStateFailed, mrv1.RemediationStateSucceeded: + return reconcile.Result{}, nil + // for all other cases we want to reconcile object in ten seconds, to give time for the object update + default: + return reconcile.Result{Requeue: true, RequeueAfter: 10 * time.Second}, nil + } +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/controllers/machineremediation/remediator.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/controllers/machineremediation/remediator.go new file mode 100644 index 0000000000..89664752a6 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/controllers/machineremediation/remediator.go @@ -0,0 +1,15 @@ +package machineremediation + +import ( + "context" + + mrv1 "kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1" +) + +// Remediator apply machine remediation strategy under a specific infrastructure. +type Remediator interface { + // Reboot the machine. + Reboot(context.Context, *mrv1.MachineRemediation) error + // Recreate the machine. + Recreate(context.Context, *mrv1.MachineRemediation) error +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/operator/components/components.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/operator/components/components.go new file mode 100644 index 0000000000..db27d82ade --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/operator/components/components.go @@ -0,0 +1,44 @@ +package components + +const ( + // ComponentMachineDisruptionBudget contains name for MachineDisruptionBudget component + ComponentMachineDisruptionBudget = "machine-disruption-budget" + // ComponentMachineHealthCheck contains name for MachineHealthCheck component + ComponentMachineHealthCheck = "machine-health-check" + // ComponentMachineRemediation contains name for MachineRemediation component + ComponentMachineRemediation = "machine-remediation" + // ComponentMachineRemediationOperator contains name for MachineRemediationOperator component + ComponentMachineRemediationOperator = "machine-remediation-operator" +) + +var ( + // Components contains names of all componenets that the operator should deploy + Components = []string{ + ComponentMachineDisruptionBudget, + ComponentMachineHealthCheck, + ComponentMachineRemediation, + } +) + +const ( + // EnvVarOperatorVersion contains the name of operator version environment variable + EnvVarOperatorVersion = "OPERATOR_VERSION" +) + +const ( + // CRDMachineDisruptionBudget contains the kind of the MachineDisruptionBudget CRD + CRDMachineDisruptionBudget = "machinedisruptionbudget" + // CRDMachineHealthCheck contains the kind of the MachineHealthCheck CRD + CRDMachineHealthCheck = "machinehealthcheck" + // CRDMachineRemediation contains the kind of the MachineRemediation CRD + CRDMachineRemediation = "machineremediation" +) + +var ( + // CRDS contains names of all CRD's that the operator should deploy + CRDS = []string{ + CRDMachineDisruptionBudget, + CRDMachineHealthCheck, + CRDMachineRemediation, + } +) diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/operator/components/csv.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/operator/components/csv.go new file mode 100644 index 0000000000..518fe6ae69 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/operator/components/csv.go @@ -0,0 +1,214 @@ +package components + +import ( + "encoding/json" + "fmt" + + "github.com/coreos/go-semver/semver" + csvv1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1" + + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const description = `The **machine remediation operator** deploys components to monitor and remediate unhealthy machines for different platforms, it works on top of cluster-api controllers. + +It should deploy three controllers: + +* [machine-health-check](https://github.com/kubevirt/machine-remediation-operator/blob/master/docs/machine-health-check.md) controller +* [machine-disruption-budget](https://github.com/kubevirt/machine-remediation-operator/blob/master/docs/machine-disruption-budget.md) controller +* [machine-remediation](https://github.com/kubevirt/machine-remediation-operator/blob/master/docs/machine-remediation.md) controller` + +const almExamples = `[ + { + "apiVersion":"machineremediation.kubevirt.io/v1alpha1", + "kind":"MachineRemediationOperator", + "metadata": { + "name":"mro", + "namespace":"openshift-machine-api" + }, + "spec": { + "imagePullPolicy":"IfNotPresent", + } + } +]` + +// ClusterServiceVersionData contains all data needed for CSV generation +type ClusterServiceVersionData struct { + Namespace string + ContainerPrefix string + ContainerTag string + ImagePullPolicy corev1.PullPolicy + Verbosity string + CSVVersion string + ReplacesCSVVersion string + CreatedAtTimestamp string +} + +type csvClusterPermissions struct { + ServiceAccountName string `json:"serviceAccountName"` + Rules []rbacv1.PolicyRule `json:"rules"` +} +type csvDeployments struct { + Name string `json:"name"` + Spec appsv1.DeploymentSpec `json:"spec,omitempty"` +} + +type csvStrategySpec struct { + ClusterPermissions []csvClusterPermissions `json:"clusterPermissions"` + Deployments []csvDeployments `json:"deployments"` +} + +// NewClusterServiceVersion returns new ClusterServiceVersion object +func NewClusterServiceVersion(data *ClusterServiceVersionData) (*csvv1.ClusterServiceVersion, error) { + operatorData := &DeploymentData{ + Name: ComponentMachineRemediationOperator, + Namespace: data.Namespace, + ImageRepository: data.ContainerPrefix, + PullPolicy: corev1.PullPolicy(data.ImagePullPolicy), + Verbosity: data.Verbosity, + OperatorVersion: data.ContainerTag, + } + operator := NewDeployment(operatorData) + + strategySpec := csvStrategySpec{ + ClusterPermissions: []csvClusterPermissions{ + { + ServiceAccountName: ComponentMachineRemediationOperator, + Rules: Rules[ComponentMachineRemediationOperator], + }, + }, + Deployments: []csvDeployments{ + { + Name: ComponentMachineRemediationOperator, + Spec: operator.Spec, + }, + }, + } + + strategySpecJSONBytes, err := json.Marshal(strategySpec) + if err != nil { + return nil, err + } + + csv := &csvv1.ClusterServiceVersion{ + TypeMeta: metav1.TypeMeta{ + Kind: csvv1.ClusterServiceVersionKind, + APIVersion: csvv1.ClusterServiceVersionAPIVersion, + }, + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("%s.%s", ComponentMachineRemediationOperator, data.CSVVersion), + Namespace: "placeholder", + Annotations: map[string]string{ + "capabilities": "Full Lifecycle", + "categories": "OpenShift Optional", + "containerImage": getImage(ComponentMachineRemediationOperator, data.ContainerPrefix, data.ContainerTag), + "createdAt": data.CreatedAtTimestamp, + "repository": "https://github.com/kubevirt/machine-remediation-operator", + "certified": "false", + "support": "KubeVirt", + "alm-examples": almExamples, + "description": "Deploys components to monitor and remediate unhealthy machines", + }, + }, + Spec: csvv1.ClusterServiceVersionSpec{ + DisplayName: "Machine Remediation Operator", + Description: description, + Keywords: []string{"remediation", "fencing", "HA", "health", "cluster-api"}, + Version: *semver.New(data.CSVVersion), + Maturity: "alpha", + Maintainers: []csvv1.Maintainer{{ + Name: "KubeVirt project", + Email: "kubevirt-dev@googlegroups.com", + }}, + Provider: csvv1.AppLink{ + Name: "Machine Remediation Operator project", + }, + Links: []csvv1.AppLink{ + { + Name: "KubeVirt", + URL: "https://kubevirt.io", + }, + { + Name: "Source Code", + URL: "https://github.com/kubevirt/machine-remediation-operator", + }, + }, + Labels: map[string]string{ + "alm-owner-kubevirt": "machineremediationoperator", + "operated-by": "machineremediationoperator", + }, + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "alm-owner-kubevirt": "machineremediationoperator", + "operated-by": "machineremediationoperator", + }, + }, + InstallModes: []csvv1.InstallMode{ + { + Type: csvv1.InstallModeTypeOwnNamespace, + Supported: true, + }, + { + Type: csvv1.InstallModeTypeSingleNamespace, + Supported: true, + }, + { + Type: csvv1.InstallModeTypeMultiNamespace, + Supported: true, + }, + { + Type: csvv1.InstallModeTypeAllNamespaces, + Supported: true, + }, + }, + InstallStrategy: csvv1.NamedInstallStrategy{ + StrategyName: "deployment", + StrategySpecRaw: json.RawMessage(strategySpecJSONBytes), + }, + CustomResourceDefinitions: csvv1.CustomResourceDefinitions{ + + Owned: []csvv1.CRDDescription{ + { + Name: "machineremediationoperators.machineremediation.kubevirt.io", + Version: "v1alpha1", + Kind: "MachineRemediationOperator", + DisplayName: "Machine Remediation Operator deployment", + Description: "Represents a Machine Remediation Operator deployment", + SpecDescriptors: []csvv1.SpecDescriptor{ + + { + Description: "The ImagePullPolicy to use for the Machine Remediation components.", + DisplayName: "ImagePullPolicy", + Path: "imagePullPolicy", + XDescriptors: []string{"urn:alm:descriptor:io.kubernetes:imagePullPolicy"}, + }, + { + Description: "The ImageRegistry to use for the Machine Remediation components.", + DisplayName: "ImageRegistry", + Path: "imageRegistry", + XDescriptors: []string{"urn:alm:descriptor:text"}, + }, + }, + StatusDescriptors: []csvv1.StatusDescriptor{ + { + Description: "Explanation for the current status of the cluster.", + DisplayName: "Conditions", + Path: "conditions", + XDescriptors: []string{"urn:alm:descriptor:io.kubernetes.conditions"}, + }, + }, + }, + }, + }, + }, + } + + if data.ReplacesCSVVersion != "" { + csv.Spec.Replaces = fmt.Sprintf("%s.%s", ComponentMachineRemediationOperator, data.ReplacesCSVVersion) + } + + return csv, nil +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/operator/components/deployments.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/operator/components/deployments.go new file mode 100644 index 0000000000..1efa5c661a --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/operator/components/deployments.go @@ -0,0 +1,156 @@ +package components + +import ( + "fmt" + + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/utils/pointer" + + mrv1 "kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1" +) + +// DeploymentData contains all needed data to create new deployment object +type DeploymentData struct { + Name string + Namespace string + ImageRepository string + PullPolicy corev1.PullPolicy + Verbosity string + OperatorVersion string +} + +func getImage(name string, imageRepository string, imageTag string) string { + return fmt.Sprintf("%s/%s:%s", imageRepository, name, imageTag) +} + +// NewDeployment returns new deployment object +func NewDeployment(data *DeploymentData) *appsv1.Deployment { + template := newPodTemplateSpec(data) + + return &appsv1.Deployment{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "apps/v1", + Kind: "Deployment", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: data.Name, + Namespace: data.Namespace, + Labels: map[string]string{ + mrv1.SchemeGroupVersion.Group: data.Name, + }, + }, + Spec: appsv1.DeploymentSpec{ + Strategy: appsv1.DeploymentStrategy{ + Type: appsv1.RollingUpdateDeploymentStrategyType, + }, + Replicas: pointer.Int32Ptr(1), + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + mrv1.SchemeGroupVersion.Group: data.Name, + mrv1.SchemeGroupVersion.Group + "/version": data.OperatorVersion, + }, + }, + Template: *template, + }, + } +} + +func newPodTemplateSpec(data *DeploymentData) *corev1.PodTemplateSpec { + containers := newContainers(data) + tolerations := []corev1.Toleration{ + { + Key: "node-role.kubernetes.io/master", + Effect: corev1.TaintEffectNoSchedule, + }, + { + Key: "CriticalAddonsOnly", + Operator: corev1.TolerationOpExists, + }, + { + Key: "node.kubernetes.io/not-ready", + Effect: corev1.TaintEffectNoExecute, + Operator: corev1.TolerationOpExists, + TolerationSeconds: pointer.Int64Ptr(120), + }, + { + Key: "node.kubernetes.io/unreachable", + Effect: corev1.TaintEffectNoExecute, + Operator: corev1.TolerationOpExists, + TolerationSeconds: pointer.Int64Ptr(120), + }, + } + + return &corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + mrv1.SchemeGroupVersion.Group: data.Name, + mrv1.SchemeGroupVersion.Group + "/version": data.OperatorVersion, + }, + }, + Spec: corev1.PodSpec{ + Affinity: &corev1.Affinity{ + PodAntiAffinity: &corev1.PodAntiAffinity{ + PreferredDuringSchedulingIgnoredDuringExecution: []corev1.WeightedPodAffinityTerm{ + { + Weight: 50, + PodAffinityTerm: corev1.PodAffinityTerm{ + LabelSelector: &metav1.LabelSelector{ + MatchExpressions: []metav1.LabelSelectorRequirement{ + { + Key: mrv1.SchemeGroupVersion.Group, + Operator: metav1.LabelSelectorOpIn, + Values: []string{data.Name}, + }, + }, + }, + TopologyKey: "kubernetes.io/hostname", + }, + }, + }, + }, + }, + Containers: containers, + NodeSelector: map[string]string{"node-role.kubernetes.io/master": ""}, + SecurityContext: &corev1.PodSecurityContext{ + RunAsNonRoot: pointer.BoolPtr(true), + }, + ServiceAccountName: data.Name, + Tolerations: tolerations, + }, + } +} + +func newContainers(data *DeploymentData) []corev1.Container { + resources := corev1.ResourceRequirements{ + Requests: map[corev1.ResourceName]resource.Quantity{ + corev1.ResourceMemory: resource.MustParse("20Mi"), + corev1.ResourceCPU: resource.MustParse("10m"), + }, + } + args := []string{ + "--logtostderr=true", + fmt.Sprintf("--v=%s", data.Verbosity), + fmt.Sprintf("--namespace=%s", data.Namespace), + } + + containers := []corev1.Container{ + { + Name: data.Name, + Image: getImage(data.Name, data.ImageRepository, data.OperatorVersion), + Command: []string{fmt.Sprintf("/usr/bin/%s", data.Name)}, + Args: args, + Resources: resources, + ImagePullPolicy: data.PullPolicy, + Env: []corev1.EnvVar{ + { + Name: EnvVarOperatorVersion, + Value: data.OperatorVersion, + }, + }, + }, + } + return containers +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/operator/components/mro.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/operator/components/mro.go new file mode 100644 index 0000000000..eca20921ed --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/operator/components/mro.go @@ -0,0 +1,30 @@ +package components + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + mrv1 "kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1" +) + +// NewMachineRemediationOperator retruns new MachineRemediationOperator object +func NewMachineRemediationOperator(name string, namespace string, imageRepository string, pullPolicy corev1.PullPolicy, operatorVersion string) *mrv1.MachineRemediationOperator { + return &mrv1.MachineRemediationOperator{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "machineremediation.kubevirt.io/v1alpha1", + Kind: "MachineRemediationOperator", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + Labels: map[string]string{ + mrv1.SchemeGroupVersion.Group: "", + mrv1.SchemeGroupVersion.Group + "/version": operatorVersion, + }, + }, + Spec: mrv1.MachineRemediationOperatorSpec{ + ImagePullPolicy: pullPolicy, + ImageRegistry: imageRepository, + }, + } +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/operator/components/rbac.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/operator/components/rbac.go new file mode 100644 index 0000000000..4ec598d898 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/operator/components/rbac.go @@ -0,0 +1,376 @@ +package components + +import ( + corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + mrv1 "kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1" +) + +var ( + // Rules contains rules for all machine remediation components + Rules = map[string][]rbacv1.PolicyRule{ + ComponentMachineDisruptionBudget: []rbacv1.PolicyRule{ + { + APIGroups: []string{ + "machine.openshift.io", + }, + Resources: []string{ + rbacv1.ResourceAll, + }, + Verbs: []string{ + "get", + "list", + "watch", + }, + }, + { + APIGroups: []string{ + "machineremediation.kubevirt.io", + }, + Resources: []string{ + "machinedisruptionbudgets", + "machinedisruptionbudgets/status", + }, + Verbs: []string{ + "get", + "list", + "update", + "watch", + }, + }, + { + APIGroups: []string{ + "", + }, + Resources: []string{ + "nodes", + }, + Verbs: []string{ + "get", + }, + }, + { + APIGroups: []string{ + "", + }, + Resources: []string{ + "configmaps", + }, + Verbs: []string{ + rbacv1.VerbAll, + }, + }, + { + APIGroups: []string{ + "", + }, + Resources: []string{ + "events", + }, + Verbs: []string{ + "create", + "list", + "watch", + "patch", + }, + }, + }, + ComponentMachineHealthCheck: []rbacv1.PolicyRule{ + { + APIGroups: []string{ + "machine.openshift.io", + }, + Resources: []string{ + "machines", + }, + Verbs: []string{ + "delete", + "get", + "list", + "watch", + }, + }, + { + APIGroups: []string{ + "machineremediation.kubevirt.io", + }, + Resources: []string{ + "machinedisruptionbudgets", + "machinedisruptionbudgets/status", + "machinehealthchecks", + }, + Verbs: []string{ + "get", + "list", + "update", + "watch", + }, + }, + { + APIGroups: []string{ + "machineremediation.kubevirt.io", + }, + Resources: []string{ + "machineremediations", + }, + Verbs: []string{ + "create", + "get", + "list", + "watch", + }, + }, + { + APIGroups: []string{ + "", + }, + Resources: []string{ + "configmaps", + }, + Verbs: []string{ + rbacv1.VerbAll, + }, + }, + { + APIGroups: []string{ + "", + }, + Resources: []string{ + "nodes", + }, + Verbs: []string{ + "get", + "list", + "watch", + }, + }, + { + APIGroups: []string{ + "", + }, + Resources: []string{ + "events", + }, + Verbs: []string{ + "create", + "list", + "watch", + "patch", + }, + }, + }, + ComponentMachineRemediation: []rbacv1.PolicyRule{ + { + APIGroups: []string{ + "machine.openshift.io", + }, + Resources: []string{ + "machines", + }, + Verbs: []string{ + "get", + "list", + "watch", + }, + }, + { + APIGroups: []string{ + "machineremediation.kubevirt.io", + }, + Resources: []string{ + "machineremediations", + "machineremediations/status", + }, + Verbs: []string{ + "delete", + "get", + "list", + "update", + "watch", + }, + }, + { + APIGroups: []string{ + "", + }, + Resources: []string{ + "nodes", + }, + Verbs: []string{ + "delete", + "get", + "list", + "watch", + }, + }, + { + APIGroups: []string{ + "metal3.io", + }, + Resources: []string{ + "baremetalhosts", + }, + Verbs: []string{ + "get", + "list", + "update", + "watch", + }, + }, + { + APIGroups: []string{ + "", + }, + Resources: []string{ + "configmaps", + }, + Verbs: []string{ + rbacv1.VerbAll, + }, + }, + { + APIGroups: []string{ + "", + }, + Resources: []string{ + "events", + }, + Verbs: []string{ + "create", + "list", + "watch", + "patch", + }, + }, + }, + ComponentMachineRemediationOperator: { + { + APIGroups: []string{ + "machineremediation.kubevirt.io", + }, + Resources: []string{ + "machineremediationoperators", + "machineremediationoperators/status", + }, + Verbs: []string{ + "get", + "list", + "update", + "watch", + }, + }, + { + APIGroups: []string{ + "", + }, + Resources: []string{ + "serviceaccounts", + }, + Verbs: []string{ + rbacv1.VerbAll, + }, + }, + { + APIGroups: []string{ + "apps", + }, + Resources: []string{ + "deployments", + }, + Verbs: []string{ + rbacv1.VerbAll, + }, + }, + { + APIGroups: []string{ + "apiextensions.k8s.io", + }, + Resources: []string{ + "customresourcedefinitions", + }, + Verbs: []string{ + rbacv1.VerbAll, + }, + }, + { + APIGroups: []string{ + "rbac.authorization.k8s.io", + }, + Resources: []string{ + "clusterroles", + "clusterrolebindings", + }, + Verbs: []string{ + rbacv1.VerbAll, + }, + }, + }, + } +) + +// NewServiceAccount returns new ServiceAccount object +func NewServiceAccount(name string, namespace string, operatorVersion string) *corev1.ServiceAccount { + return &corev1.ServiceAccount{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "ServiceAccount", + }, + ObjectMeta: metav1.ObjectMeta{ + Namespace: namespace, + Name: name, + Labels: map[string]string{ + mrv1.SchemeGroupVersion.Group: "", + mrv1.SchemeGroupVersion.Group + "/version": operatorVersion, + }, + }, + } +} + +// NewClusterRole returns new ClusterRole object +func NewClusterRole(name string, rules []rbacv1.PolicyRule, operatorVersion string) *rbacv1.ClusterRole { + return &rbacv1.ClusterRole{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "rbac.authorization.k8s.io/v1", + Kind: "ClusterRole", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Labels: map[string]string{ + mrv1.SchemeGroupVersion.Group: "", + mrv1.SchemeGroupVersion.Group + "/version": operatorVersion, + }, + }, + Rules: rules, + } +} + +// NewClusterRoleBinding returns new ClusterRoleBinding object +func NewClusterRoleBinding(name string, namespace string, operatorVersion string) *rbacv1.ClusterRoleBinding { + return &rbacv1.ClusterRoleBinding{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "rbac.authorization.k8s.io/v1", + Kind: "ClusterRoleBinding", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Labels: map[string]string{ + mrv1.SchemeGroupVersion.Group: "", + mrv1.SchemeGroupVersion.Group + "/version": operatorVersion, + }, + }, + RoleRef: rbacv1.RoleRef{ + APIGroup: "rbac.authorization.k8s.io", + Kind: "ClusterRole", + Name: name, + }, + Subjects: []rbacv1.Subject{ + { + Kind: "ServiceAccount", + Namespace: namespace, + Name: name, + }, + }, + } +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/operator/operator.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/operator/operator.go new file mode 100644 index 0000000000..3f07ac9a31 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/operator/operator.go @@ -0,0 +1,300 @@ +package operator + +import ( + "context" + "fmt" + "os" + "time" + + "github.com/golang/glog" + + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + mrv1 "kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1" + "kubevirt.io/machine-remediation-operator/pkg/consts" + "kubevirt.io/machine-remediation-operator/pkg/operator/components" + + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + "sigs.k8s.io/controller-runtime/pkg/source" +) + +const machineRemediationOperatorFinalizer string = "foregroundDeleteMachineRemediationOperator" + +var _ reconcile.Reconciler = &ReconcileMachineRemediationOperator{} + +// ReconcileMachineRemediationOperator reconciles a MachineRemediationOperator object +type ReconcileMachineRemediationOperator struct { + // This client, initialized using mgr.Client() above, is a split client + // that reads objects from the cache and writes to the apiserver + client client.Client + namespace string + operatorVersion string + crdsManifestsDir string +} + +// Add creates a new MachineRemediationOperator Controller and adds it to the Manager. +// The Manager will set fields on the Controller and start it when the Manager is started. +func Add(mgr manager.Manager, opts manager.Options) error { + r, err := newReconciler(mgr, opts) + if err != nil { + return err + } + return add(mgr, r) +} + +func newReconciler(mgr manager.Manager, opts manager.Options) (reconcile.Reconciler, error) { + return &ReconcileMachineRemediationOperator{ + client: mgr.GetClient(), + namespace: opts.Namespace, + operatorVersion: os.Getenv(components.EnvVarOperatorVersion), + crdsManifestsDir: "/data", + }, nil +} + +// add adds a new Controller to mgr with r as the reconcile.Reconciler +func add(mgr manager.Manager, r reconcile.Reconciler) error { + // Create a new controller + c, err := controller.New("machine-remediation-operator-controller", mgr, controller.Options{Reconciler: r}) + if err != nil { + return err + } + + return c.Watch(&source.Kind{Type: &mrv1.MachineRemediationOperator{}}, &handler.EnqueueRequestForObject{}) +} + +// Reconcile monitors MachineRemediationOperator and bring all machine remediation components to desired state +// Note: +// The Controller will requeue the Request to be processed again if the returned error is non-nil or +// Result.Requeue is true, otherwise upon completion it will remove the work from the queue. +func (r *ReconcileMachineRemediationOperator) Reconcile(request reconcile.Request) (reconcile.Result, error) { + glog.V(4).Infof("Reconciling MachineRemediationOperator triggered by %s/%s\n", request.Namespace, request.Name) + + // Get MachineRemediation from request + mro := &mrv1.MachineRemediationOperator{} + err := r.client.Get(context.TODO(), request.NamespacedName, mro) + if err != nil { + if errors.IsNotFound(err) { + // Request object not found, could have been deleted after reconcile request. + // Owned objects are automatically garbage collected. For additional cleanup logic use finalizers. + // Return and don't requeue + return reconcile.Result{}, nil + } + // Error reading the object - requeue the request. + return reconcile.Result{}, err + } + + // if MachineRemediationObject was deleted, remove all relevant componenets and remove finalizer + if mro.DeletionTimestamp != nil { + if err := r.deleteComponents(); err != nil { + return reconcile.Result{}, err + } + + mro.Finalizers = nil + if err := r.client.Update(context.TODO(), mro); err != nil { + return reconcile.Result{}, err + } + + return reconcile.Result{}, nil + } + + // add finalizer to prevent deletion of MachineRemediationOperator objet + if !hasFinalizer(mro) { + addFinalizer(mro) + if err := r.client.Update(context.TODO(), mro); err != nil { + return reconcile.Result{}, err + } + return reconcile.Result{}, nil + } + + if err := r.createOrUpdateComponents(mro); err != nil { + glog.Errorf("Failed to create components: %v", err) + if err := r.statusDegraded(mro, err.Error(), "Failed to create all components"); err != nil { + glog.Errorf("Failed to update operator status: %v", err) + return reconcile.Result{}, err + } + return reconcile.Result{}, err + } + + for _, component := range components.Components { + ready, err := r.isDeploymentReady(component, consts.NamespaceOpenshiftMachineAPI) + if err != nil { + if err := r.statusProgressing(mro, err.Error(), fmt.Sprintf("Failed to get deployment %q", component)); err != nil { + glog.Errorf("Failed to update operator status: %v", err) + return reconcile.Result{}, err + } + return reconcile.Result{Requeue: true, RequeueAfter: time.Second * 5}, nil + } + + if !ready { + if err := r.statusProgressing(mro, "Deployment is not ready", fmt.Sprintf("Deployment %q is not ready", component)); err != nil { + glog.Errorf("Failed to update operator status: %v", err) + return reconcile.Result{}, err + } + return reconcile.Result{Requeue: true, RequeueAfter: time.Second * 5}, nil + } + } + + if err := r.statusAvailable(mro); err != nil { + return reconcile.Result{}, err + } + return reconcile.Result{}, nil +} + +func (r *ReconcileMachineRemediationOperator) createOrUpdateComponents(mro *mrv1.MachineRemediationOperator) error { + for _, crd := range components.CRDS { + glog.Infof("Creating or updating CRD %q", crd) + if err := r.createOrUpdateCustomResourceDefinition(crd); err != nil { + return err + } + } + + for _, component := range components.Components { + glog.Infof("Creating objects for component %q", component) + if err := r.createOrUpdateServiceAccount(component, consts.NamespaceOpenshiftMachineAPI); err != nil { + return err + } + + if err := r.createOrUpdateClusterRole(component); err != nil { + return err + } + + if err := r.createOrUpdateClusterRoleBinding(component, consts.NamespaceOpenshiftMachineAPI); err != nil { + return err + } + + deployData := &components.DeploymentData{ + Name: component, + Namespace: consts.NamespaceOpenshiftMachineAPI, + ImageRepository: mro.Spec.ImageRegistry, + PullPolicy: mro.Spec.ImagePullPolicy, + OperatorVersion: r.operatorVersion, + Verbosity: "4", + } + + if err := r.createOrUpdateDeployment(deployData); err != nil { + return err + } + } + return nil +} + +func (r *ReconcileMachineRemediationOperator) deleteComponents() error { + for _, component := range components.Components { + glog.Infof("Deleting objets for component %q", component) + if err := r.deleteDeployment(component, consts.NamespaceOpenshiftMachineAPI); err != nil { + return err + } + + if err := r.deleteClusterRoleBinding(component); err != nil { + return err + } + + if err := r.deleteClusterRole(component); err != nil { + return err + } + + if err := r.deleteServiceAccount(component, consts.NamespaceOpenshiftMachineAPI); err != nil { + return err + } + } + + for _, crd := range components.CRDS { + glog.Infof("Deleting CRD %q", crd) + if err := r.deleteCustomResourceDefinition(crd); err != nil { + return err + } + } + + return nil +} + +func (r *ReconcileMachineRemediationOperator) statusAvailable(mro *mrv1.MachineRemediationOperator) error { + now := time.Now() + mro.Status.Conditions = []mrv1.MachineRemediationOperatorStatusCondition{ + { + Type: mrv1.OperatorAvailable, + Status: corev1.ConditionTrue, + LastTransitionTime: metav1.Time{Time: now}, + }, + { + Type: mrv1.OperatorProgressing, + Status: corev1.ConditionFalse, + LastTransitionTime: metav1.Time{Time: now}, + }, + { + Type: mrv1.OperatorDegraded, + Status: corev1.ConditionFalse, + LastTransitionTime: metav1.Time{Time: now}, + }, + } + return r.client.Status().Update(context.TODO(), mro) +} + +func (r *ReconcileMachineRemediationOperator) statusDegraded(mro *mrv1.MachineRemediationOperator, reason string, message string) error { + now := time.Now() + mro.Status.Conditions = []mrv1.MachineRemediationOperatorStatusCondition{ + { + Type: mrv1.OperatorAvailable, + Status: corev1.ConditionFalse, + LastTransitionTime: metav1.Time{Time: now}, + }, + { + Type: mrv1.OperatorProgressing, + Status: corev1.ConditionFalse, + LastTransitionTime: metav1.Time{Time: now}, + }, + { + Type: mrv1.OperatorDegraded, + Status: corev1.ConditionTrue, + LastTransitionTime: metav1.Time{Time: now}, + Reason: reason, + Message: message, + }, + } + return r.client.Status().Update(context.TODO(), mro) +} + +func (r *ReconcileMachineRemediationOperator) statusProgressing(mro *mrv1.MachineRemediationOperator, reason string, message string) error { + now := time.Now() + mro.Status.Conditions = []mrv1.MachineRemediationOperatorStatusCondition{ + { + Type: mrv1.OperatorAvailable, + Status: corev1.ConditionFalse, + LastTransitionTime: metav1.Time{Time: now}, + }, + { + Type: mrv1.OperatorProgressing, + Status: corev1.ConditionTrue, + LastTransitionTime: metav1.Time{Time: now}, + Reason: reason, + Message: message, + }, + { + Type: mrv1.OperatorDegraded, + Status: corev1.ConditionFalse, + LastTransitionTime: metav1.Time{Time: now}, + }, + } + return r.client.Status().Update(context.TODO(), mro) +} + +func addFinalizer(mro *mrv1.MachineRemediationOperator) { + if !hasFinalizer(mro) { + mro.Finalizers = append(mro.Finalizers, machineRemediationOperatorFinalizer) + } +} + +func hasFinalizer(mro *mrv1.MachineRemediationOperator) bool { + for _, f := range mro.Finalizers { + if f == machineRemediationOperatorFinalizer { + return true + } + } + return false +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/operator/resources.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/operator/resources.go new file mode 100644 index 0000000000..670af0507b --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/operator/resources.go @@ -0,0 +1,301 @@ +package operator + +import ( + "context" + "fmt" + "io/ioutil" + "strings" + + "github.com/ghodss/yaml" + + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + extv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/utils/pointer" + + mrv1 "kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1" + "kubevirt.io/machine-remediation-operator/pkg/operator/components" +) + +func (r *ReconcileMachineRemediationOperator) getDeployment(name string, namespace string) (*appsv1.Deployment, error) { + deploy := &appsv1.Deployment{} + key := types.NamespacedName{ + Name: name, + Namespace: namespace, + } + if err := r.client.Get(context.TODO(), key, deploy); err != nil { + return nil, err + } + return deploy, nil +} + +func (r *ReconcileMachineRemediationOperator) createOrUpdateDeployment(data *components.DeploymentData) error { + if data.ImageRepository == "" { + imageRepository, err := r.getOperatorImageRepository() + if err != nil { + return err + } + + data.ImageRepository = imageRepository + } + + if data.PullPolicy == "" { + data.PullPolicy = corev1.PullIfNotPresent + } + + newDeploy := components.NewDeployment(data) + newDeploy.Spec.Replicas = pointer.Int32Ptr(2) + + oldDeploy, err := r.getDeployment(data.Name, data.Namespace) + if errors.IsNotFound(err) { + if err := r.client.Create(context.TODO(), newDeploy); err != nil { + return err + } + return nil + } + + if err != nil { + return err + } + + // do not override some user specific configuration + newDeploy.Annotations = oldDeploy.Annotations + newDeploy.Labels = oldDeploy.Labels + newDeploy.Spec.Replicas = oldDeploy.Spec.Replicas + + // do not update the status, deployment controller one who responsible to update it + newDeploy.Status = oldDeploy.Status + return r.client.Update(context.TODO(), newDeploy) +} + +func (r *ReconcileMachineRemediationOperator) getOperatorImageRepository() (string, error) { + ns, err := getOperatorNamespace() + if err != nil { + return "", err + } + + operator, err := r.getDeployment(components.ComponentMachineRemediationOperator, ns) + if err != nil { + return "", err + } + + image := strings.Split(operator.Spec.Template.Spec.Containers[0].Image, "/") + return strings.Join(image[:len(image)-1], "/"), nil +} + +func getOperatorNamespace() (string, error) { + data, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace") + if err != nil { + return "", fmt.Errorf("failed to get operator namespace: %v", err) + } + + if ns := strings.TrimSpace(string(data)); len(ns) > 0 { + return ns, nil + } + + return "", fmt.Errorf("failed to get operator namespace: %v", err) +} + +func (r *ReconcileMachineRemediationOperator) deleteDeployment(name string, namespace string) error { + deploy, err := r.getDeployment(name, namespace) + if errors.IsNotFound(err) { + return nil + } + if err != nil { + return err + } + return r.client.Delete(context.TODO(), deploy) +} + +func (r *ReconcileMachineRemediationOperator) isDeploymentReady(name string, namespace string) (bool, error) { + d, err := r.getDeployment(name, namespace) + if err != nil { + return false, err + } + if d.Generation <= d.Status.ObservedGeneration && + d.Status.Replicas == *d.Spec.Replicas && + d.Status.UpdatedReplicas == d.Status.Replicas && + d.Status.UnavailableReplicas == 0 { + return true, nil + } + return false, nil +} + +func (r *ReconcileMachineRemediationOperator) getServiceAccount(name string, namespace string) (*corev1.ServiceAccount, error) { + sa := &corev1.ServiceAccount{} + key := types.NamespacedName{ + Name: name, + Namespace: namespace, + } + if err := r.client.Get(context.TODO(), key, sa); err != nil { + return nil, err + } + return sa, nil +} + +func (r *ReconcileMachineRemediationOperator) createOrUpdateServiceAccount(name string, namespace string) error { + newServiceAccount := components.NewServiceAccount(name, namespace, r.operatorVersion) + + _, err := r.getServiceAccount(name, namespace) + if errors.IsNotFound(err) { + if err := r.client.Create(context.TODO(), newServiceAccount); err != nil { + return err + } + return nil + } + + if err != nil { + return err + } + + return r.client.Update(context.TODO(), newServiceAccount) +} + +func (r *ReconcileMachineRemediationOperator) deleteServiceAccount(name string, namespace string) error { + sa, err := r.getServiceAccount(name, namespace) + if errors.IsNotFound(err) { + return nil + } + if err != nil { + return err + } + return r.client.Delete(context.TODO(), sa) +} + +func (r *ReconcileMachineRemediationOperator) getClusterRole(name string) (*rbacv1.ClusterRole, error) { + cr := &rbacv1.ClusterRole{} + key := types.NamespacedName{ + Name: name, + Namespace: metav1.NamespaceNone, + } + if err := r.client.Get(context.TODO(), key, cr); err != nil { + return nil, err + } + return cr, nil +} + +func (r *ReconcileMachineRemediationOperator) createOrUpdateClusterRole(name string) error { + newClusterRole := components.NewClusterRole(name, components.Rules[name], r.operatorVersion) + + _, err := r.getClusterRole(name) + if errors.IsNotFound(err) { + if err := r.client.Create(context.TODO(), newClusterRole); err != nil { + return err + } + return nil + } + + if err != nil { + return err + } + + return r.client.Update(context.TODO(), newClusterRole) +} + +func (r *ReconcileMachineRemediationOperator) deleteClusterRole(name string) error { + cr, err := r.getClusterRole(name) + if errors.IsNotFound(err) { + return nil + } + if err != nil { + return err + } + return r.client.Delete(context.TODO(), cr) +} + +func (r *ReconcileMachineRemediationOperator) getClusterRoleBinding(name string) (*rbacv1.ClusterRoleBinding, error) { + crb := &rbacv1.ClusterRoleBinding{} + key := types.NamespacedName{ + Name: name, + Namespace: metav1.NamespaceNone, + } + if err := r.client.Get(context.TODO(), key, crb); err != nil { + return nil, err + } + return crb, nil +} + +func (r *ReconcileMachineRemediationOperator) createOrUpdateClusterRoleBinding(name string, namespace string) error { + newClusterRoleBinding := components.NewClusterRoleBinding(name, namespace, r.operatorVersion) + + _, err := r.getClusterRoleBinding(name) + if errors.IsNotFound(err) { + if err := r.client.Create(context.TODO(), newClusterRoleBinding); err != nil { + return err + } + return nil + } + + if err != nil { + return err + } + + return r.client.Update(context.TODO(), newClusterRoleBinding) +} + +func (r *ReconcileMachineRemediationOperator) deleteClusterRoleBinding(name string) error { + crb, err := r.getClusterRoleBinding(name) + if errors.IsNotFound(err) { + return nil + } + if err != nil { + return err + } + return r.client.Delete(context.TODO(), crb) +} + +func getCustomResourceDefinitionFilePath(name string, dir string) string { + return fmt.Sprintf("%s/%s_%s_%s.yaml", dir, "machineremediation", mrv1.SchemeGroupVersion.Version, name) +} + +func (r *ReconcileMachineRemediationOperator) getCustomResourceDefinition(kind string) (*extv1beta1.CustomResourceDefinition, error) { + crd := &extv1beta1.CustomResourceDefinition{} + key := types.NamespacedName{ + Name: fmt.Sprintf("%ss.%s", kind, mrv1.SchemeGroupVersion.Group), + Namespace: metav1.NamespaceNone, + } + if err := r.client.Get(context.TODO(), key, crd); err != nil { + return nil, err + } + return crd, nil +} + +func (r *ReconcileMachineRemediationOperator) createOrUpdateCustomResourceDefinition(kind string) error { + newCRD := &extv1beta1.CustomResourceDefinition{} + crdFile, err := ioutil.ReadFile(getCustomResourceDefinitionFilePath(kind, r.crdsManifestsDir)) + if err != nil { + return err + } + if err := yaml.Unmarshal(crdFile, newCRD); err != nil { + return err + } + + oldCRD, err := r.getCustomResourceDefinition(kind) + if errors.IsNotFound(err) { + if err := r.client.Create(context.TODO(), newCRD); err != nil { + return err + } + return nil + } + if err != nil { + return err + } + + newCRD.ResourceVersion = oldCRD.ResourceVersion + return r.client.Update(context.TODO(), newCRD) +} + +func (r *ReconcileMachineRemediationOperator) deleteCustomResourceDefinition(kind string) error { + crd, err := r.getCustomResourceDefinition(kind) + if errors.IsNotFound(err) { + return nil + } + if err != nil { + return err + } + return r.client.Delete(context.TODO(), crd) +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/utils/conditions/conditions.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/utils/conditions/conditions.go new file mode 100644 index 0000000000..4f9c6ff3ad --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/utils/conditions/conditions.go @@ -0,0 +1,125 @@ +package conditions + +import ( + "context" + "fmt" + + "github.com/ghodss/yaml" + "github.com/golang/glog" + mrv1 "kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1" + + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/types" + + "sigs.k8s.io/controller-runtime/pkg/client" +) + +// GetNodeCondition returns node condition by type +func GetNodeCondition(node *corev1.Node, conditionType corev1.NodeConditionType) *corev1.NodeCondition { + for _, cond := range node.Status.Conditions { + if cond.Type == conditionType { + return &cond + } + } + return nil +} + +// NodeHasCondition returns true when the node has condition of the specific type and status +func NodeHasCondition(node *corev1.Node, conditionType corev1.NodeConditionType, contidionStatus corev1.ConditionStatus) bool { + for _, cond := range node.Status.Conditions { + if cond.Type == conditionType && cond.Status == contidionStatus { + return true + } + } + return false +} + +// UnhealthyConditions contains a list of UnhealthyCondition +type UnhealthyConditions struct { + Items []UnhealthyCondition `json:"items"` +} + +// UnhealthyCondition is the representation of unhealthy conditions under the config map +type UnhealthyCondition struct { + Name corev1.NodeConditionType `json:"name"` + Status corev1.ConditionStatus `json:"status"` + Timeout string `json:"timeout"` +} + +// CreateDummyUnhealthyConditionsConfigMap creates dummy config map with default unhealthy conditions +func createDummyUnhealthyConditionsConfigMap() (*corev1.ConfigMap, error) { + unhealthyConditions := &UnhealthyConditions{ + Items: []UnhealthyCondition{ + { + Name: "Ready", + Status: "Unknown", + Timeout: "300s", + }, + { + Name: "Ready", + Status: "False", + Timeout: "300s", + }, + }, + } + conditionsData, err := yaml.Marshal(unhealthyConditions) + if err != nil { + return nil, err + } + return &corev1.ConfigMap{Data: map[string]string{"conditions": string(conditionsData)}}, nil +} + +// GetNodeUnhealthyConditions returns node unhealthy conditions +func GetNodeUnhealthyConditions(node *corev1.Node, cmUnealthyConditions *corev1.ConfigMap) ([]UnhealthyCondition, error) { + data, ok := cmUnealthyConditions.Data["conditions"] + if !ok { + return nil, fmt.Errorf("can not find \"conditions\" under the configmap") + } + + var unealthyConditions UnhealthyConditions + err := yaml.Unmarshal([]byte(data), &unealthyConditions) + if err != nil { + glog.Errorf("failed to umarshal: %v", err) + return nil, err + } + + conditions := []UnhealthyCondition{} + for _, c := range unealthyConditions.Items { + cond := GetNodeCondition(node, c.Name) + if cond != nil && cond.Status == c.Status { + conditions = append(conditions, c) + } + } + return conditions, nil +} + +// GetUnhealthyConditionsConfigMap get config map with unhealthy node conditions, when the config map +// does not exist, returns dummy config map with default unhealthy conditions +func GetUnhealthyConditionsConfigMap(c client.Client, namespace string) (*corev1.ConfigMap, error) { + cmUnhealtyConditions := &corev1.ConfigMap{} + cmKey := types.NamespacedName{ + Name: mrv1.ConfigMapNodeUnhealthyConditions, + Namespace: namespace, + } + err := c.Get(context.TODO(), cmKey, cmUnhealtyConditions) + if err != nil { + // Error reading the object - requeue the request + if !errors.IsNotFound(err) { + return nil, err + } + + // creates dummy config map with default values if it does not exist + cmUnhealtyConditions, err = createDummyUnhealthyConditionsConfigMap() + if err != nil { + return nil, err + } + glog.Infof( + "ConfigMap %s not found under the namespace %s, fallback to default values: %s", + mrv1.ConfigMapNodeUnhealthyConditions, + namespace, + cmUnhealtyConditions.Data["conditions"], + ) + } + return cmUnhealtyConditions, nil +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/utils/machines/machines.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/utils/machines/machines.go new file mode 100644 index 0000000000..983c913b94 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/utils/machines/machines.go @@ -0,0 +1,79 @@ +package machines + +import ( + "context" + "fmt" + + "github.com/golang/glog" + mrv1 "kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1" + "kubevirt.io/machine-remediation-operator/pkg/utils/conditions" + + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + + mapiv1 "sigs.k8s.io/cluster-api/pkg/apis/machine/v1beta1" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +// IsMachineHealthy returns true if the the machine is running and machine node is healthy +func IsMachineHealthy(c client.Client, machine *mapiv1.Machine) (bool, error) { + if machine.Status.NodeRef == nil { + return false, fmt.Errorf("Machine %s does not have node reference", machine.Name) + } + + node := &v1.Node{} + key := client.ObjectKey{Namespace: metav1.NamespaceNone, Name: machine.Status.NodeRef.Name} + err := c.Get(context.TODO(), key, node) + if err != nil { + return false, err + } + + cmUnhealtyConditions, err := conditions.GetUnhealthyConditionsConfigMap(c, machine.Namespace) + if err != nil { + return false, err + } + + nodeUnhealthyConditions, err := conditions.GetNodeUnhealthyConditions(node, cmUnhealtyConditions) + if err != nil { + return false, err + } + + if len(nodeUnhealthyConditions) > 0 { + glog.Infof("Machine %q unhealthy because of conditions: %v", machine.Name, nodeUnhealthyConditions) + return false, nil + } + + return true, nil +} + +// GetMachineMachineDisruptionBudgets returns list of machine disruption budgets that suit for the machine +func GetMachineMachineDisruptionBudgets(c client.Client, machine *mapiv1.Machine) ([]*mrv1.MachineDisruptionBudget, error) { + if len(machine.Labels) == 0 { + return nil, fmt.Errorf("no MachineDisruptionBudgets found for machine %v because it has no labels", machine.Name) + } + + list := &mrv1.MachineDisruptionBudgetList{} + err := c.List(context.TODO(), list, client.InNamespace(machine.Namespace)) + if err != nil { + return nil, err + } + + var mdbs []*mrv1.MachineDisruptionBudget + for i := range list.Items { + mdb := &list.Items[i] + selector, err := metav1.LabelSelectorAsSelector(mdb.Spec.Selector) + if err != nil { + glog.Warningf("invalid selector: %v", err) + continue + } + + // If a mdb with a nil or empty selector creeps in, it should match nothing, not everything. + if selector.Empty() || !selector.Matches(labels.Set(machine.Labels)) { + continue + } + mdbs = append(mdbs, mdb) + } + + return mdbs, nil +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/utils/testing/testing.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/utils/testing/testing.go new file mode 100644 index 0000000000..6a9dc95bd0 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/utils/testing/testing.go @@ -0,0 +1,190 @@ +package testing + +import ( + "fmt" + "time" + + bmov1 "github.com/metal3-io/baremetal-operator/pkg/apis/metal3/v1alpha1" + mrv1 "kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1" + "kubevirt.io/machine-remediation-operator/pkg/consts" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + mapiv1 "sigs.k8s.io/cluster-api/pkg/apis/machine/v1beta1" +) + +var ( + // KnownDate contains date that can be used under tests + KnownDate = metav1.Time{Time: time.Date(1985, 06, 03, 0, 0, 0, 0, time.Local)} +) + +// FooBar returns foo:bar map that can be used as default label +func FooBar() map[string]string { + return map[string]string{"foo": "bar"} +} + +// NewSelector returns new LabelSelector +func NewSelector(labels map[string]string) *metav1.LabelSelector { + return &metav1.LabelSelector{MatchLabels: labels} +} + +// NewSelectorFooBar returns new foo:bar label selector +func NewSelectorFooBar() *metav1.LabelSelector { + return NewSelector(FooBar()) +} + +// NewMinAvailableMachineDisruptionBudget returns new MachineDisruptionBudget with min available parameter +func NewMinAvailableMachineDisruptionBudget(minAvailable int32) *mrv1.MachineDisruptionBudget { + return &mrv1.MachineDisruptionBudget{ + TypeMeta: metav1.TypeMeta{Kind: "MachineDisruptionBudget"}, + ObjectMeta: metav1.ObjectMeta{ + Name: "foobar", + Namespace: consts.NamespaceOpenshiftMachineAPI, + }, + Spec: mrv1.MachineDisruptionBudgetSpec{ + MinAvailable: &minAvailable, + Selector: NewSelectorFooBar(), + }, + } +} + +// NewMaxUnavailableMachineDisruptionBudget returns new MachineDisruptionBudget with max unavailable parameter +func NewMaxUnavailableMachineDisruptionBudget(maxUnavailable int32) *mrv1.MachineDisruptionBudget { + return &mrv1.MachineDisruptionBudget{ + TypeMeta: metav1.TypeMeta{Kind: "MachineDisruptionBudget"}, + ObjectMeta: metav1.ObjectMeta{ + Name: "foobar", + Namespace: consts.NamespaceOpenshiftMachineAPI, + }, + Spec: mrv1.MachineDisruptionBudgetSpec{ + MaxUnavailable: &maxUnavailable, + Selector: NewSelectorFooBar(), + }, + } +} + +// NewMachineHealthCheck returns new MachineHealthCheck object that can be used for testing +func NewMachineHealthCheck(name string) *mrv1.MachineHealthCheck { + return &mrv1.MachineHealthCheck{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: consts.NamespaceOpenshiftMachineAPI, + }, + TypeMeta: metav1.TypeMeta{ + Kind: "MachineHealthCheck", + }, + Spec: mrv1.MachineHealthCheckSpec{ + Selector: *NewSelectorFooBar(), + }, + Status: mrv1.MachineHealthCheckStatus{}, + } +} + +// NewUnhealthyConditionsConfigMap returns new config map object with unhealthy conditions +func NewUnhealthyConditionsConfigMap(name string, data string) *corev1.ConfigMap { + return &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: consts.NamespaceOpenshiftMachineAPI, + }, + TypeMeta: metav1.TypeMeta{ + Kind: "ConfigMap", + }, + Data: map[string]string{ + "conditions": data, + }, + } +} + +// NewBareMetalHost returns new bare metal host object that can be used for testing +func NewBareMetalHost(name string, online bool, powerOn bool) *bmov1.BareMetalHost { + return &bmov1.BareMetalHost{ + TypeMeta: metav1.TypeMeta{Kind: "BareMetalHost"}, + ObjectMeta: metav1.ObjectMeta{ + Annotations: make(map[string]string), + Name: name, + Namespace: consts.NamespaceOpenshiftMachineAPI, + }, + Spec: bmov1.BareMetalHostSpec{ + Online: online, + }, + Status: bmov1.BareMetalHostStatus{ + PoweredOn: powerOn, + }, + } +} + +// NewMachine returns new machine object that can be used for testing +func NewMachine(name string, nodeName string, bareMetalHostName string) *mapiv1.Machine { + m := &mapiv1.Machine{ + TypeMeta: metav1.TypeMeta{Kind: "Machine"}, + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{ + consts.AnnotationBareMetalHost: fmt.Sprintf("%s/%s", consts.NamespaceOpenshiftMachineAPI, bareMetalHostName), + }, + Name: name, + Namespace: consts.NamespaceOpenshiftMachineAPI, + OwnerReferences: []metav1.OwnerReference{{Kind: "MachineSet"}}, + Labels: FooBar(), + }, + Spec: mapiv1.MachineSpec{}, + } + if nodeName != "" { + m.Status = mapiv1.MachineStatus{ + NodeRef: &corev1.ObjectReference{ + Name: nodeName, + Namespace: metav1.NamespaceNone, + }, + } + } + return m +} + +// NewMachineRemediation returns new machine remediation object that can be used for testing +func NewMachineRemediation(name string, machineName string, remediationType mrv1.RemediationType, remediationState mrv1.RemediationState) *mrv1.MachineRemediation { + return &mrv1.MachineRemediation{ + TypeMeta: metav1.TypeMeta{Kind: "MachineRemediation"}, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: consts.NamespaceOpenshiftMachineAPI, + }, + Spec: mrv1.MachineRemediationSpec{ + MachineName: machineName, + Type: remediationType, + }, + Status: mrv1.MachineRemediationStatus{ + StartTime: &metav1.Time{Time: time.Now()}, + State: remediationState, + }, + } +} + +// NewNode returns new node object that can be used for testing +func NewNode(name string, ready bool, machineName string) *corev1.Node { + nodeReadyStatus := corev1.ConditionTrue + if !ready { + nodeReadyStatus = corev1.ConditionUnknown + } + + return &corev1.Node{ + TypeMeta: metav1.TypeMeta{Kind: "Node"}, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: metav1.NamespaceNone, + Annotations: map[string]string{ + consts.AnnotationMachine: fmt.Sprintf("%s/%s", consts.NamespaceOpenshiftMachineAPI, machineName), + }, + Labels: map[string]string{}, + }, + Status: corev1.NodeStatus{ + Conditions: []corev1.NodeCondition{ + { + Type: corev1.NodeReady, + Status: nodeReadyStatus, + LastTransitionTime: KnownDate, + }, + }, + }, + } +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/version/base.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/version/base.go new file mode 100644 index 0000000000..c628392126 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/version/base.go @@ -0,0 +1,9 @@ +package version + +var ( + gitVersion = "v0.0.0-master+$Format:%h$" + gitCommit = "$Format:%H$" // sha1 from git, output of $(git rev-parse HEAD) + gitTreeState = "" // state of git tree, either "clean" or "dirty" + + buildDate = "1970-01-01T00:00:00Z" // build date in ISO8601 format, output of $(date -u +'%Y-%m-%dT%H:%M:%SZ') +) diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/version/types.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/version/types.go new file mode 100644 index 0000000000..1b480cd2a7 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/version/types.go @@ -0,0 +1,17 @@ +package version + +// Info contains all detail regarding the version +type Info struct { + GitVersion string `json:"gitVersion"` + GitCommit string `json:"gitCommit"` + GitTreeState string `json:"gitTreeState"` + BuildDate string `json:"buildDate"` + GoVersion string `json:"goVersion"` + Compiler string `json:"compiler"` + Platform string `json:"platform"` +} + +// String returns info as a human-friendly version string. +func (info Info) String() string { + return info.GitVersion +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/pkg/version/version.go b/vendor/kubevirt.io/machine-remediation-operator/pkg/version/version.go new file mode 100644 index 0000000000..1d9d755535 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/pkg/version/version.go @@ -0,0 +1,19 @@ +package version + +import ( + "fmt" + "runtime" +) + +// Get returns version information +func Get() Info { + return Info{ + GitVersion: gitVersion, + GitCommit: gitCommit, + GitTreeState: gitTreeState, + BuildDate: buildDate, + GoVersion: runtime.Version(), + Compiler: runtime.Compiler, + Platform: fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH), + } +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/tests/machinedisruptionbudget.go b/vendor/kubevirt.io/machine-remediation-operator/tests/machinedisruptionbudget.go new file mode 100644 index 0000000000..4dd8587709 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/tests/machinedisruptionbudget.go @@ -0,0 +1,137 @@ +package e2e + +import ( + "context" + "fmt" + "time" + + "github.com/golang/glog" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/types" + + mrv1 "kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1" + "kubevirt.io/machine-remediation-operator/pkg/utils/conditions" + testsutils "kubevirt.io/machine-remediation-operator/tests/utils" + + mapiv1 "sigs.k8s.io/cluster-api/pkg/apis/machine/v1beta1" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +var _ = Describe("[Feature:MachineDisruptionBudget] MachineDisruptionBudget controller", func() { + var c client.Client + var workerNode *corev1.Node + var workerMachineSet *mapiv1.MachineSet + var testMdb *mrv1.MachineDisruptionBudget + + mdbName := "test-mdb" + getCurrentHealthyMachines := func() int32 { + updateMdb := &mrv1.MachineDisruptionBudget{} + key := types.NamespacedName{ + Name: mdbName, + Namespace: testsutils.NamespaceOpenShiftMachineAPI, + } + err := c.Get(context.TODO(), key, updateMdb) + if err != nil { + return 0 + } + return updateMdb.Status.CurrentHealthy + } + + BeforeEach(func() { + var err error + c, err = testsutils.LoadClient() + Expect(err).ToNot(HaveOccurred()) + + By("Getting worker node") + workerNodes, err := testsutils.GetWorkerNodes(c) + Expect(err).ToNot(HaveOccurred()) + + readyWorkerNodes := testsutils.FilterReadyNodes(workerNodes) + Expect(readyWorkerNodes).ToNot(BeEmpty()) + + workerNode = &readyWorkerNodes[0] + glog.V(2).Infof("Worker node %s", workerNode.Name) + + By("Getting worker machine") + workerMachine, err := testsutils.GetMachineFromNode(c, workerNode) + Expect(err).ToNot(HaveOccurred()) + glog.V(2).Infof("Worker machine %s", workerMachine.Name) + + By("Geting worker machine set") + workerMachineSet, err = testsutils.GetMachinesSetByMachine(workerMachine) + Expect(err).ToNot(HaveOccurred()) + + glog.V(2).Infof("Create machine health check with label selector: %s", workerMachine.Labels) + err = testsutils.CreateMachineHealthCheck(testsutils.MachineHealthCheckName, workerMachine.Labels) + Expect(err).ToNot(HaveOccurred()) + + unhealthyConditions := &conditions.UnhealthyConditions{ + Items: []conditions.UnhealthyCondition{ + { + Name: "Ready", + Status: "Unknown", + Timeout: "60s", + }, + }, + } + glog.V(2).Infof("Create node-unhealthy-conditions configmap") + err = testsutils.CreateUnhealthyConditionsConfigMap(unhealthyConditions) + Expect(err).ToNot(HaveOccurred()) + }) + + It("updates MDB status", func() { + minAvailable := int32(3) + testMdb = testsutils.NewMachineDisruptionBudget( + mdbName, + workerMachineSet.Spec.Selector.MatchLabels, + &minAvailable, + nil, + ) + By("Creating MachineDisruptionBudget") + err := c.Create(context.TODO(), testMdb) + Expect(err).ToNot(HaveOccurred()) + + updateMdb := &mrv1.MachineDisruptionBudget{} + Eventually(func() int32 { + key := types.NamespacedName{ + Name: mdbName, + Namespace: testsutils.NamespaceOpenShiftMachineAPI, + } + err := c.Get(context.TODO(), key, updateMdb) + if err != nil { + return 0 + } + return updateMdb.Status.Total + }, 120*time.Second, time.Second).Should(Equal(*workerMachineSet.Spec.Replicas)) + + currentHealthy := updateMdb.Status.CurrentHealthy + Expect(currentHealthy).To(Equal(workerMachineSet.Status.ReadyReplicas)) + + By(fmt.Sprintf("Stopping kubelet service on the node %s", workerNode.Name)) + err = testsutils.StopKubelet(workerNode.Name) + Expect(err).ToNot(HaveOccurred()) + + // Waiting until worker machine will have unhealthy node + Eventually(getCurrentHealthyMachines, 6*time.Minute, 10*time.Second).Should(Equal(currentHealthy - 1)) + + // Waiting until machine set will create new healthy machine + Eventually(getCurrentHealthyMachines, 15*time.Minute, 30*time.Second).Should(Equal(currentHealthy)) + }) + + AfterEach(func() { + err := c.Delete(context.TODO(), testMdb) + Expect(err).ToNot(HaveOccurred()) + + err = testsutils.DeleteMachineHealthCheck(testsutils.MachineHealthCheckName) + Expect(err).ToNot(HaveOccurred()) + + err = testsutils.DeleteKubeletKillerPods() + Expect(err).ToNot(HaveOccurred()) + + err = testsutils.DeleteUnhealthyConditionsConfigMap() + Expect(err).ToNot(HaveOccurred()) + }) +}) diff --git a/vendor/kubevirt.io/machine-remediation-operator/tests/machinehealthcheck.go b/vendor/kubevirt.io/machine-remediation-operator/tests/machinehealthcheck.go new file mode 100644 index 0000000000..a839b201a5 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/tests/machinehealthcheck.go @@ -0,0 +1,158 @@ +package e2e + +import ( + "context" + "fmt" + "time" + + "github.com/golang/glog" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/types" + + "kubevirt.io/machine-remediation-operator/pkg/utils/conditions" + testsutils "kubevirt.io/machine-remediation-operator/tests/utils" + + mapiv1 "sigs.k8s.io/cluster-api/pkg/apis/machine/v1beta1" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +const ( + machineAPIControllers = "machine-api-controllers" + machineHealthCheckControler = "machine-healthcheck-controller" +) + +var _ = Describe("[TechPreview:Feature:MachineHealthCheck] MachineHealthCheck controller", func() { + var c client.Client + var numberOfReadyWorkers int + var workerNode *corev1.Node + var workerMachine *mapiv1.Machine + + stopKubeletAndValidateMachineDeletion := func(workerNodeName *corev1.Node, workerMachine *mapiv1.Machine, timeout time.Duration) { + By(fmt.Sprintf("Stopping kubelet service on the node %s", workerNode.Name)) + err := testsutils.StopKubelet(workerNode.Name) + Expect(err).ToNot(HaveOccurred()) + + By(fmt.Sprintf("Validating that node %s has 'NotReady' condition", workerNode.Name)) + waitForNodeUnhealthyCondition(workerNode.Name) + + By(fmt.Sprintf("Validating that machine %s is deleted", workerMachine.Name)) + machine := &mapiv1.Machine{} + key := types.NamespacedName{ + Namespace: workerMachine.Namespace, + Name: workerMachine.Name, + } + Eventually(func() bool { + err := c.Get(context.TODO(), key, machine) + if err != nil { + if errors.IsNotFound(err) { + return true + } + } + glog.V(2).Infof("machine deletion timestamp %s still exists", machine.DeletionTimestamp) + return false + }, timeout, 5*time.Second).Should(BeTrue()) + } + + BeforeEach(func() { + var err error + c, err = testsutils.LoadClient() + Expect(err).ToNot(HaveOccurred()) + + workerNodes, err := testsutils.GetWorkerNodes(c) + Expect(err).ToNot(HaveOccurred()) + + readyWorkerNodes := testsutils.FilterReadyNodes(workerNodes) + Expect(readyWorkerNodes).ToNot(BeEmpty()) + + numberOfReadyWorkers = len(readyWorkerNodes) + workerNode = &readyWorkerNodes[0] + glog.V(2).Infof("Worker node %s", workerNode.Name) + + workerMachine, err = testsutils.GetMachineFromNode(c, workerNode) + Expect(err).ToNot(HaveOccurred()) + glog.V(2).Infof("Worker machine %s", workerMachine.Name) + + glog.V(2).Infof("Create machine health check with label selector: %s", workerMachine.Labels) + err = testsutils.CreateMachineHealthCheck(testsutils.MachineHealthCheckName, workerMachine.Labels) + Expect(err).ToNot(HaveOccurred()) + }) + + Context("with node-unhealthy-conditions configmap", func() { + BeforeEach(func() { + unhealthyConditions := &conditions.UnhealthyConditions{ + Items: []conditions.UnhealthyCondition{ + { + Name: "Ready", + Status: "Unknown", + Timeout: "60s", + }, + }, + } + glog.V(2).Infof("Create node-unhealthy-conditions configmap") + err := testsutils.CreateUnhealthyConditionsConfigMap(unhealthyConditions) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should delete unhealthy machine", func() { + stopKubeletAndValidateMachineDeletion(workerNode, workerMachine, 2*time.Minute) + }) + + AfterEach(func() { + glog.V(2).Infof("Delete node-unhealthy-conditions configmap") + err := testsutils.DeleteUnhealthyConditionsConfigMap() + Expect(err).ToNot(HaveOccurred()) + }) + }) + + It("should delete unhealthy machine", func() { + stopKubeletAndValidateMachineDeletion(workerNode, workerMachine, 6*time.Minute) + }) + + AfterEach(func() { + waitForWorkersToGetReady(numberOfReadyWorkers) + testsutils.DeleteMachineHealthCheck(testsutils.MachineHealthCheckName) + testsutils.DeleteKubeletKillerPods() + }) +}) + +func waitForNodeUnhealthyCondition(workerNodeName string) { + c, err := testsutils.LoadClient() + Expect(err).ToNot(HaveOccurred()) + + key := types.NamespacedName{ + Name: workerNodeName, + Namespace: testsutils.NamespaceOpenShiftMachineAPI, + } + node := &corev1.Node{} + glog.Infof("Wait until node %s will have 'Ready' condition with the status %s", node.Name, corev1.ConditionUnknown) + Eventually(func() bool { + err := c.Get(context.TODO(), key, node) + if err != nil { + return false + } + readyCond := conditions.GetNodeCondition(node, corev1.NodeReady) + glog.V(2).Infof("Node %s has 'Ready' condition with the status %s", node.Name, readyCond.Status) + return readyCond.Status == corev1.ConditionUnknown + }, testsutils.WaitLong, 10*time.Second).Should(BeTrue()) +} + +func waitForWorkersToGetReady(numberOfReadyWorkers int) { + client, err := testsutils.LoadClient() + Expect(err).ToNot(HaveOccurred()) + + glog.V(2).Infof("Wait until the environment will have %d ready workers", numberOfReadyWorkers) + Eventually(func() bool { + workerNodes, err := testsutils.GetWorkerNodes(client) + if err != nil { + return false + } + + readyWorkerNodes := testsutils.FilterReadyNodes(workerNodes) + glog.V(2).Infof("Number of ready workers %d", len(readyWorkerNodes)) + return len(readyWorkerNodes) == numberOfReadyWorkers + }, 15*time.Minute, 10*time.Second).Should(BeTrue()) +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/tests/utils/client.go b/vendor/kubevirt.io/machine-remediation-operator/tests/utils/client.go new file mode 100644 index 0000000000..4382571ed2 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/tests/utils/client.go @@ -0,0 +1,41 @@ +package utils + +import ( + "flag" + "fmt" + + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + + "sigs.k8s.io/controller-runtime/pkg/client" +) + +var kubeconfig string + +// Init will initialize the kubeconfig variable for command line parameters +func Init() { + flag.StringVar(&kubeconfig, "kubeconfig", "", "kubeconfig file") +} + +// LoadConfig builds config from kubernetes config +func LoadConfig() (*rest.Config, error) { + if kubeconfig == "" { + return rest.InClusterConfig() + } + + c, err := clientcmd.LoadFromFile(kubeconfig) + if err != nil { + return nil, fmt.Errorf("error loading KubeConfig: %v", err.Error()) + } + + return clientcmd.NewDefaultClientConfig(*c, &clientcmd.ConfigOverrides{}).ClientConfig() +} + +// LoadClient builds controller runtime client that accepts any registered type +func LoadClient() (client.Client, error) { + config, err := LoadConfig() + if err != nil { + return nil, fmt.Errorf("error creating client: %v", err.Error()) + } + return client.New(config, client.Options{}) +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/tests/utils/consts.go b/vendor/kubevirt.io/machine-remediation-operator/tests/utils/consts.go new file mode 100644 index 0000000000..9062f33883 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/tests/utils/consts.go @@ -0,0 +1,21 @@ +package utils + +import "time" + +const ( + // KubeletKillerPodName contains the name of the pod that stops kubelet process + KubeletKillerPodName = "kubelet-killer" + // MachineAnnotationKey contains machine annotation key + MachineAnnotationKey = "machine.openshift.io/machine" + // MachineHealthCheckName contains the name of the machinehealthcheck used for tests + MachineHealthCheckName = "workers-check" + // NamespaceOpenShiftMachineAPI contains the openshift-machine-api namespace name + NamespaceOpenShiftMachineAPI = "openshift-machine-api" + // WorkerNodeRoleLabel contains the label of worker node + WorkerNodeRoleLabel = "node-role.kubernetes.io/worker" +) + +const ( + // WaitLong contains number of minutes to wait before long timeout + WaitLong = 10 * time.Minute +) diff --git a/vendor/kubevirt.io/machine-remediation-operator/tests/utils/machines.go b/vendor/kubevirt.io/machine-remediation-operator/tests/utils/machines.go new file mode 100644 index 0000000000..a9ed0b8a8c --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/tests/utils/machines.go @@ -0,0 +1,67 @@ +package utils + +import ( + "context" + "fmt" + + corev1 "k8s.io/api/core/v1" + "k8s.io/client-go/tools/cache" + + mapiv1 "sigs.k8s.io/cluster-api/pkg/apis/machine/v1beta1" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +// GetMachine get a machine by its name from the default machine API namespace. +func GetMachine(c client.Client, machineName string) (*mapiv1.Machine, error) { + machine := &mapiv1.Machine{} + if err := c.Get(context.TODO(), client.ObjectKey{Namespace: NamespaceOpenShiftMachineAPI, Name: machineName}, machine); err != nil { + return nil, fmt.Errorf("error querying api for machine object: %v", err) + } + return machine, nil +} + +// GetMachineFromNode returns the machine referenced by the "controllernode.MachineAnnotationKey" annotation in the given node +func GetMachineFromNode(c client.Client, node *corev1.Node) (*mapiv1.Machine, error) { + machineNamespaceKey, ok := node.Annotations[MachineAnnotationKey] + if !ok { + return nil, fmt.Errorf("node %q does not have a MachineAnnotationKey %q", node.Name, MachineAnnotationKey) + } + namespace, machineName, err := cache.SplitMetaNamespaceKey(machineNamespaceKey) + if err != nil { + return nil, fmt.Errorf("machine annotation format is incorrect %v: %v", machineNamespaceKey, err) + } + + if namespace != NamespaceOpenShiftMachineAPI { + return nil, fmt.Errorf("Machine %q is forbidden to live outside of default %v namespace", machineNamespaceKey, NamespaceOpenShiftMachineAPI) + } + + machine, err := GetMachine(c, machineName) + if err != nil { + return nil, fmt.Errorf("error querying api for machine object: %v", err) + } + + return machine, nil +} + +// GetMachinesSetByMachine retruns machine owner machine set +func GetMachinesSetByMachine(machine *mapiv1.Machine) (*mapiv1.MachineSet, error) { + c, err := LoadClient() + if err != nil { + return nil, err + } + + if len(machine.OwnerReferences) == 0 { + return nil, fmt.Errorf("machine %s does not have owner controller", machine.Name) + } + + machineSet := &mapiv1.MachineSet{} + key := client.ObjectKey{ + Namespace: NamespaceOpenShiftMachineAPI, + Name: machine.OwnerReferences[0].Name, + } + err = c.Get(context.TODO(), key, machineSet) + if err != nil { + return nil, err + } + return machineSet, nil +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/tests/utils/mdbs.go b/vendor/kubevirt.io/machine-remediation-operator/tests/utils/mdbs.go new file mode 100644 index 0000000000..5a746932b1 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/tests/utils/mdbs.go @@ -0,0 +1,23 @@ +package utils + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + mrv1 "kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1" +) + +// NewMachineDisruptionBudget returns new MachineDisruptionObject with specified parameters +func NewMachineDisruptionBudget(name string, machineLabels map[string]string, minAvailable *int32, maxUnavailable *int32) *mrv1.MachineDisruptionBudget { + selector := &metav1.LabelSelector{MatchLabels: machineLabels} + return &mrv1.MachineDisruptionBudget{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: NamespaceOpenShiftMachineAPI, + }, + Spec: mrv1.MachineDisruptionBudgetSpec{ + MinAvailable: minAvailable, + MaxUnavailable: maxUnavailable, + Selector: selector, + }, + } +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/tests/utils/mhcs.go b/vendor/kubevirt.io/machine-remediation-operator/tests/utils/mhcs.go new file mode 100644 index 0000000000..ade067d17d --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/tests/utils/mhcs.go @@ -0,0 +1,156 @@ +package utils + +import ( + "context" + + "github.com/ghodss/yaml" + "sigs.k8s.io/controller-runtime/pkg/client" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/rand" + + mrv1 "kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1" + "kubevirt.io/machine-remediation-operator/pkg/utils/conditions" +) + +// CreateMachineHealthCheck will create MachineHealthCheck CR with the relevant selector +func CreateMachineHealthCheck(name string, labels map[string]string) error { + c, err := LoadClient() + if err != nil { + return err + } + + mhc := &mrv1.MachineHealthCheck{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: NamespaceOpenShiftMachineAPI, + }, + Spec: mrv1.MachineHealthCheckSpec{ + Selector: metav1.LabelSelector{ + MatchLabels: labels, + }, + }, + } + return c.Create(context.TODO(), mhc) +} + +// DeleteMachineHealthCheck deletes machine health check by name +func DeleteMachineHealthCheck(healthcheckName string) error { + c, err := LoadClient() + if err != nil { + return err + } + + key := types.NamespacedName{ + Name: healthcheckName, + Namespace: NamespaceOpenShiftMachineAPI, + } + healthcheck := &mrv1.MachineHealthCheck{} + if err := c.Get(context.TODO(), key, healthcheck); err != nil { + return err + } + return c.Delete(context.TODO(), healthcheck) +} + +// CreateUnhealthyConditionsConfigMap creates node-unhealthy-conditions configmap with relevant conditions +func CreateUnhealthyConditionsConfigMap(unhealthyConditions *conditions.UnhealthyConditions) error { + c, err := LoadClient() + if err != nil { + return err + } + + cm := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: NamespaceOpenShiftMachineAPI, + Name: mrv1.ConfigMapNodeUnhealthyConditions, + }, + } + + conditionsData, err := yaml.Marshal(unhealthyConditions) + if err != nil { + return err + } + + cm.Data = map[string]string{"conditions": string(conditionsData)} + return c.Create(context.TODO(), cm) +} + +// DeleteUnhealthyConditionsConfigMap deletes node-unhealthy-conditions configmap +func DeleteUnhealthyConditionsConfigMap() error { + c, err := LoadClient() + if err != nil { + return err + } + + key := types.NamespacedName{ + Name: mrv1.ConfigMapNodeUnhealthyConditions, + Namespace: NamespaceOpenShiftMachineAPI, + } + cm := &corev1.ConfigMap{} + if err := c.Get(context.TODO(), key, cm); err != nil { + return err + } + + return c.Delete(context.TODO(), cm) +} + +// StopKubelet creates pod in the node PID namespace that stops kubelet process +func StopKubelet(nodeName string) error { + client, err := LoadClient() + if err != nil { + return err + } + + _true := true + pod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: KubeletKillerPodName + rand.String(5), + Namespace: NamespaceOpenShiftMachineAPI, + Labels: map[string]string{ + KubeletKillerPodName: "", + }, + }, + Spec: corev1.PodSpec{ + RestartPolicy: corev1.RestartPolicyNever, + Containers: []corev1.Container{ + { + Name: KubeletKillerPodName, + Image: "busybox", + Command: []string{"pkill", "-STOP", "hyperkube"}, + SecurityContext: &corev1.SecurityContext{ + Privileged: &_true, + }, + }, + }, + NodeName: nodeName, + HostPID: true, + }, + } + return client.Create(context.TODO(), pod) +} + +// DeleteKubeletKillerPods deletes kubelet killer pod +func DeleteKubeletKillerPods() error { + c, err := LoadClient() + if err != nil { + return err + } + podList := &corev1.PodList{} + if err := c.List( + context.TODO(), + podList, + client.InNamespace(NamespaceOpenShiftMachineAPI), + client.MatchingLabels(map[string]string{KubeletKillerPodName: ""}), + ); err != nil { + return err + } + + for _, pod := range podList.Items { + if err := c.Delete(context.TODO(), &pod); err != nil { + return err + } + } + return nil +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/tests/utils/nodes.go b/vendor/kubevirt.io/machine-remediation-operator/tests/utils/nodes.go new file mode 100644 index 0000000000..515a093841 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/tests/utils/nodes.go @@ -0,0 +1,45 @@ +package utils + +import ( + "context" + + corev1 "k8s.io/api/core/v1" + + "sigs.k8s.io/controller-runtime/pkg/client" +) + +// GetWorkerNodes returns all nodes with the nodeWorkerRoleLabel label +func GetWorkerNodes(c client.Client) ([]corev1.Node, error) { + workerNodes := &corev1.NodeList{} + err := c.List( + context.TODO(), + workerNodes, + client.InNamespace(NamespaceOpenShiftMachineAPI), + client.MatchingLabels(map[string]string{WorkerNodeRoleLabel: ""}), + ) + if err != nil { + return nil, err + } + return workerNodes.Items, nil +} + +// FilterReadyNodes fileter the list of nodes and returns the list with ready nodes +func FilterReadyNodes(nodes []corev1.Node) []corev1.Node { + var readyNodes []corev1.Node + for _, n := range nodes { + if IsNodeReady(&n) { + readyNodes = append(readyNodes, n) + } + } + return readyNodes +} + +// IsNodeReady returns true once node is ready +func IsNodeReady(node *corev1.Node) bool { + for _, c := range node.Status.Conditions { + if c.Type == corev1.NodeReady { + return c.Status == corev1.ConditionTrue + } + } + return false +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/tools/csv-generator/csv-generator.go b/vendor/kubevirt.io/machine-remediation-operator/tools/csv-generator/csv-generator.go new file mode 100644 index 0000000000..a477fd0550 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/tools/csv-generator/csv-generator.go @@ -0,0 +1,73 @@ +/* + * This file is part of the KubeVirt project + * + * 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. + * + * Copyright 2018 Red Hat, Inc. + * + */ + +package main + +import ( + "flag" + "fmt" + "io/ioutil" + "os" + + corev1 "k8s.io/api/core/v1" + + mrv1 "kubevirt.io/machine-remediation-operator/pkg/apis/machineremediation/v1alpha1" + "kubevirt.io/machine-remediation-operator/pkg/operator/components" + "kubevirt.io/machine-remediation-operator/tools/utils" +) + +func main() { + namespace := flag.String("namespace", "opensgift-machine-api", "Namespace to use.") + repository := flag.String("repository", "index.docker.io/kubevirt", "Image Repository to use.") + version := flag.String("version", "latest", "version to use.") + pullPolicy := flag.String("pullPolicy", "IfNotPresent", "ImagePullPolicy to use.") + verbosity := flag.String("verbosity", "2", "Verbosity level to use.") + csvVersion := flag.String("csv-version", "0.0.0", "ClusterServiceVersion version.") + csvPreviousVersion := flag.String("csv-previous-version", "", "ClusterServiceVersion version to replace.") + dumpCRD := flag.Bool("dump-crd", false, "Dump operator CRD together with CSV to the stdout.") + + flag.Parse() + + imagePullPolicy := corev1.PullPolicy(*pullPolicy) + data := &components.ClusterServiceVersionData{ + CSVVersion: *csvVersion, + ContainerPrefix: *repository, + ContainerTag: *version, + ImagePullPolicy: imagePullPolicy, + Namespace: *namespace, + ReplacesCSVVersion: *csvPreviousVersion, + Verbosity: *verbosity, + } + csv, err := components.NewClusterServiceVersion(data) + if err != nil { + panic(fmt.Errorf("failed to get CSV component: %v", err)) + } + utils.MarshallObject(csv, os.Stdout) + + if *dumpCRD { + crdFilePath := fmt.Sprintf("/data/%s_%s_%s.yaml", "machineremediation", mrv1.SchemeGroupVersion.Version, "machineremediationoperator") + crdFile, err := ioutil.ReadFile(crdFilePath) + if err != nil { + panic(fmt.Errorf("failed to read CRD file: %v", err)) + } + if _, err := os.Stdout.Write(crdFile); err != nil { + panic(fmt.Errorf("failed to write CRD to stdout: %v", err)) + } + } +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/tools/manifest-templator/manifest-templator.go b/vendor/kubevirt.io/machine-remediation-operator/tools/manifest-templator/manifest-templator.go new file mode 100644 index 0000000000..1ec98c1626 --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/tools/manifest-templator/manifest-templator.go @@ -0,0 +1,116 @@ +/* + * This file is part of the KubeVirt project + * + * 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. + * + * Copyright 2018 Red Hat, Inc. + * + */ + +package main + +import ( + "flag" + "fmt" + "io/ioutil" + "os" + "path/filepath" + "text/template" + + "github.com/spf13/pflag" +) + +type templateData struct { + Namespace string + ContainerTag string + ContainerPrefix string + ImagePullPolicy string + Verbosity string + CSVVersion string + CSVPreviousVersion string + GeneratedManifests map[string]string +} + +func main() { + namespace := flag.String("namespace", "", "") + containerPrefix := flag.String("container-prefix", "", "") + containerTag := flag.String("container-tag", "", "") + imagePullPolicy := flag.String("image-pull-policy", "IfNotPresent", "") + verbosity := flag.String("verbosity", "2", "") + genDir := flag.String("generated-manifests-dir", "", "") + inputFile := flag.String("input-file", "", "") + processFiles := flag.Bool("process-files", false, "") + processVars := flag.Bool("process-vars", false, "") + + csvVersion := flag.String("csv-version", "0.0.0", "") + csvPreviousVersion := flag.String("csv-previous-version", "0.0.0", "") + + pflag.CommandLine.AddGoFlagSet(flag.CommandLine) + pflag.CommandLine.ParseErrorsWhitelist.UnknownFlags = true + pflag.Parse() + + if !(*processFiles || *processVars) { + panic("at least one of process-files or process-vars must be true") + } + + data := &templateData{ + GeneratedManifests: make(map[string]string), + } + + if *processVars { + data.Namespace = *namespace + data.ContainerTag = *containerTag + data.ContainerPrefix = *containerPrefix + data.ImagePullPolicy = *imagePullPolicy + data.Verbosity = fmt.Sprintf("%s", *verbosity) + data.CSVVersion = *csvVersion + data.CSVPreviousVersion = *csvPreviousVersion + } else { + data.Namespace = "{{.Namespace}}" + data.ContainerTag = "{{.ContainerTag}}" + data.ContainerPrefix = "{{.ContainerPrefix}}" + data.ImagePullPolicy = "{{.ImagePullPolicy}}" + data.Verbosity = "{{.Verbosity}}" + data.CSVVersion = "{{.CSVVersion}}" + data.CSVPreviousVersion = "{{.CSVPreviousVersion}}" + } + + if *processFiles { + getGeneratedFiles(*genDir, data) + } + + tmpl := template.Must(template.ParseFiles(*inputFile)) + err := tmpl.Execute(os.Stdout, data) + if err != nil { + panic(err) + } +} + +func getGeneratedFiles(rootDir string, data *templateData) { + manifests, err := ioutil.ReadDir(rootDir) + if err != nil { + panic(err) + } + + for _, manifest := range manifests { + if manifest.IsDir() { + getGeneratedFiles(filepath.Join(rootDir, manifest.Name()), data) + continue + } + b, err := ioutil.ReadFile(filepath.Join(rootDir, manifest.Name())) + if err != nil { + panic(err) + } + data.GeneratedManifests[manifest.Name()] = string(b) + } +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/tools/resource-generator/resource-generator.go b/vendor/kubevirt.io/machine-remediation-operator/tools/resource-generator/resource-generator.go new file mode 100644 index 0000000000..88d2c61bad --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/tools/resource-generator/resource-generator.go @@ -0,0 +1,79 @@ +/* + * This file is part of the KubeVirt project + * + * 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. + * + * Copyright 2018 Red Hat, Inc. + * + */ + +package main + +import ( + "flag" + "fmt" + "os" + + corev1 "k8s.io/api/core/v1" + + "kubevirt.io/machine-remediation-operator/pkg/operator/components" + "kubevirt.io/machine-remediation-operator/tools/utils" +) + +func main() { + // General arguments + resourceType := flag.String("type", "", "Type of resource to generate.") + namespace := flag.String("namespace", "kube-system", "Namespace to use.") + repository := flag.String("repository", "kubevirt", "Image Repository to use.") + version := flag.String("version", "latest", "version to use.") + pullPolicy := flag.String("pullPolicy", "IfNotPresent", "ImagePullPolicy to use.") + verbosity := flag.String("verbosity", "2", "Verbosity level to use.") + + flag.Parse() + + imagePullPolicy := corev1.PullPolicy(*pullPolicy) + + switch *resourceType { + case "machine-remediation-operator": + // create service account for the machine-remediation-operator + sa := components.NewServiceAccount(*resourceType, *namespace, *version) + utils.MarshallObject(sa, os.Stdout) + + // create cluster role for the machine-remediation-operator + cr := components.NewClusterRole(*resourceType, components.Rules[*resourceType], *version) + utils.MarshallObject(cr, os.Stdout) + + // create cluster role binding for the machine-remediation-operator + crb := components.NewClusterRoleBinding(*resourceType, *namespace, *version) + utils.MarshallObject(crb, os.Stdout) + + // create operator deployment + operatorData := &components.DeploymentData{ + Name: *resourceType, + Namespace: *namespace, + ImageRepository: *repository, + PullPolicy: imagePullPolicy, + Verbosity: *verbosity, + OperatorVersion: *version, + } + operator := components.NewDeployment(operatorData) + utils.MarshallObject(operator, os.Stdout) + case "machine-remediation-operator-cr": + // create operator CR + mro := components.NewMachineRemediationOperator(*resourceType, *namespace, *repository, imagePullPolicy, *version) + mro.Name = "mro" + utils.MarshallObject(mro, os.Stdout) + default: + panic(fmt.Errorf("unknown resource type %s", *resourceType)) + } +} diff --git a/vendor/kubevirt.io/machine-remediation-operator/tools/tools.go b/vendor/kubevirt.io/machine-remediation-operator/tools/tools.go new file mode 100644 index 0000000000..732262d4aa --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/tools/tools.go @@ -0,0 +1,9 @@ +// Package tools contains code generation utilities +// This package imports things required by build scripts, to force `go mod` to see them as dependencies +package tools + +import ( + _ "k8s.io/code-generator/cmd/client-gen" + _ "k8s.io/code-generator/cmd/deepcopy-gen" + _ "sigs.k8s.io/controller-tools/cmd/controller-gen" +) diff --git a/vendor/kubevirt.io/machine-remediation-operator/tools/utils/marshaller.go b/vendor/kubevirt.io/machine-remediation-operator/tools/utils/marshaller.go new file mode 100644 index 0000000000..7419f94c9c --- /dev/null +++ b/vendor/kubevirt.io/machine-remediation-operator/tools/utils/marshaller.go @@ -0,0 +1,65 @@ +package utils + +import ( + "encoding/json" + "io" + "strings" + + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + + "github.com/ghodss/yaml" +) + +// MarshallObject cretes yaml templates for our manifests +func MarshallObject(obj interface{}, writer io.Writer) error { + jsonBytes, err := json.Marshal(obj) + if err != nil { + return err + } + + var r unstructured.Unstructured + if err := json.Unmarshal(jsonBytes, &r.Object); err != nil { + return err + } + + // remove status and metadata.creationTimestamp + unstructured.RemoveNestedField(r.Object, "metadata", "creationTimestamp") + unstructured.RemoveNestedField(r.Object, "spec", "template", "metadata", "creationTimestamp") + unstructured.RemoveNestedField(r.Object, "status") + + // remove CSV specific empty fields + unstructured.RemoveNestedField(r.Object, "spec", "apiservicedefinitions") + + jsonBytes, err = json.Marshal(r.Object) + if err != nil { + return err + } + + yamlBytes, err := yaml.JSONToYAML(jsonBytes) + if err != nil { + return err + } + + // fix templates by removing unneeded single quotes... + s := string(yamlBytes) + s = strings.Replace(s, "'{{", "{{", -1) + s = strings.Replace(s, "}}'", "}}", -1) + + // fix double quoted strings by removing unneeded single quotes... + s = strings.Replace(s, " '\"", " \"", -1) + s = strings.Replace(s, "\"'\n", "\"\n", -1) + + yamlBytes = []byte(s) + + _, err = writer.Write([]byte("---\n")) + if err != nil { + return err + } + + _, err = writer.Write(yamlBytes) + if err != nil { + return err + } + + return nil +}