Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add native Azure Blob support to BucketController #513

Closed
wants to merge 56 commits into from

Conversation

laozc
Copy link
Contributor

@laozc laozc commented Dec 4, 2021

This PR adds native Azure Blob support to the BucketController
which enables the integration in Azure environment.

---
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: Bucket
metadata:
  name: azure-blob
 namespace: flux-system
spec:
  interval: 1m
  provider: azure
  bucketName: flux
  endpoint: https://STORAGE_ACCOUNT_NAME.blob.core.windows.net/
  secretRef:
    name: blob-credentials

To provide the key the user may choose to use account key or resourceId.

kubectl create secret generic blob-credentials --namespace flux-system --from-literal secretkey=[STORAGE_ACCOUNT_KEY]
or
kubectl create secret generic blob-credentials --namespace flux-system --from-literal accesskey=[STORAGE_ACCOUNT_RESOURCE_ID]

When using resourceId as accesskey, the source-controller deployment is required to have Azure cloud-config (/etc/kubernetes/azure.json) mounted.

@laozc laozc force-pushed the azblob branch 4 times, most recently from 658faf0 to 77bf538 Compare December 4, 2021 04:18
Signed-off-by: Zhongcheng Lao <Zhongcheng.Lao@microsoft.com>
Signed-off-by: Zhongcheng Lao <Zhongcheng.Lao@microsoft.com>
Signed-off-by: Zhongcheng Lao <Zhongcheng.Lao@microsoft.com>
hiddeco and others added 7 commits December 6, 2021 13:49
This commit introduces new Condition types to the v1beta1 API,
facilitating easier observation of (potentially) problematic state for
end-users.

- `ArtifactUnavailableCondition`: indicates there is no artifact
  available for the resource. This Condition should be set by the
  reconciler as soon as it observes the absence of an artifact for a
  source.
- `CheckoutFailedCondition`: indicates a transient or persistent
  checkout failure. This Condition should be set by the reconciler as
  soon as it observes a Git checkout failure, including any
  prerequisites like the unavailability of the referenced Secret used
  for authentication. It should be deleted as soon as a successful
  checkout has been observed again.
- `SourceVerifiedCondition`: indicates the integrity of the source has
  been verified. The Condition should be set to True or False by the
  reconciler based on the result of the integrity check.
  If there is no verification mode and/or secret configured, the
  Condition should be removed.
- `IncludeUnavailableCondition`: indicates one of the referenced
  includes is not available. This Condition should for example be set
  by the reconciler when the include does not exist, or does not have
  an artifact. If the includes become available, it should be deleted.
- `ArtifactOutdatedCondition`: indicates the current artifact of the
  source is outdated. This Condition should for example be set by the
  reconciler when it notices there is a newer revision for an artifact,
  or the previously included artifacts differ from the current available
  ones. The Condition should be removed after writing a new artifact
  to the storage.

Signed-off-by: Hidde Beydals <hello@hidde.co>
This commit ensures all API objects implement the interfaces used by
the runtime package to work with conditions, etc., and prepares the
test suite to work with the `pkg/runtime/testenv` wrapper.

Changes are made in a backwards compatible way (that being: the
existing code can still be build and works as expected), but without
proper dependency boundaries. The result of this is that the API
package temporary depends on the runtime package, which is resolved
when all reconcilers have been refactored and the API package does
no longer contain condition modifying functions.

Signed-off-by: Hidde Beydals <hello@hidde.co>
NOTE: Remove `hasArtifactUpdated` in the future once it's no longer
used.

Signed-off-by: Hidde Beydals <hello@hidde.co>
The problem with `GetInterval()` was that the returned type was of
`metav1.Duration`, while almost anywhere it was used, a type of
`time.Duration` was requested. The result of this was that we had to
call `GetInterval().Duration` all the time, which would become a bit
cumbersome after awhile.

To prevent this, we introduce a new `GetRequeueAfter() time.Duration`
method, which both results the right type, and bears a name that is
easier to remember where the value is used most; while setting the
`Result.RequeueAfter` during reconcile operations.

The introduction of this method deprecates `GetInterval()`, which
should be removed in a future MINOR release.

Signed-off-by: Sunny <darkowlzz@protonmail.com>

Co-authored-by: Hidde Beydals <hello@hidde.co>
Signed-off-by: Sunny <darkowlzz@protonmail.com>
Also, introduce FetchFailedCondition for generic fetch failures.

Signed-off-by: Sunny <darkowlzz@protonmail.com>

Co-authored-by: Hidde Beydals <hello@hidde.co>
Signed-off-by: Sunny <darkowlzz@protonmail.com>

Co-authored-by: Hidde Beydals <hello@hidde.co>
@stefanprodan
Copy link
Member

When using resourceId as accesskey, the source-controller deployment is required to have Azure cloud-config (/etc/kubernetes/azure.json) mounted.

Please remove this option, mounting files inside a Flux controller breaks multi-tenancy.

phillebaba
phillebaba previously approved these changes Dec 6, 2021
controllers/bucket_controller.go Outdated Show resolved Hide resolved
controllers/bucket_controller.go Outdated Show resolved Hide resolved
controllers/bucket_controller.go Outdated Show resolved Hide resolved
controllers/bucket_controller.go Outdated Show resolved Hide resolved
@phillebaba
Copy link
Member

@laozc looks good, left a few smaller comments 🌹

Copy link
Member

@hiddeco hiddeco left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally supportive of adding support for Azure Blob, but I think the changes need to be carefully aligned with the work in #455 and additional pending work in https://github.com/fluxcd/source-controller/tree/reconcilers-dev-bucket.

Which means it may take some time before the prerequisites for this PR are in place, and I can provide a precise insight into what needs further addressing.

@phillebaba phillebaba self-requested a review December 6, 2021 14:36
@phillebaba phillebaba dismissed their stale review December 6, 2021 14:37

Remove Approval

Signed-off-by: Zhongcheng Lao <Zhongcheng.Lao@microsoft.com>
@laozc
Copy link
Contributor Author

laozc commented Dec 7, 2021

I'll hold on this PR for a bit until the #455 is merged.

@laozc
Copy link
Contributor Author

laozc commented Dec 7, 2021

When using resourceId as accesskey, the source-controller deployment is required to have Azure cloud-config (/etc/kubernetes/azure.json) mounted.

Please remove this option, mounting files inside a Flux controller breaks multi-tenancy.

Could you elaborate more details on your concern?
This Azure cloud config file is a cluster-wide configuration which contains the Service Principle or Managed Identity used by the cluster.
Services in the cluster may use the identity to communicate with Azure Management APIs.
It does not contain specific information to any resource linked to a Bucket object.
When mouting the cloud config in Flux controller, the controller gains the same permission as the cluster on operating Azure resources.
The user may provide only Azure Resource ID without touching the actual storage access key, which enhances the security in Azure environment.

darkowlzz and others added 6 commits December 7, 2021 21:51
Signed-off-by: Sunny <darkowlzz@protonmail.com>
This commit rewrites the `BucketReconciler` to new standards, while
implementing the newly introduced Condition types, and trying to
adhere better to Kubernetes API conventions.

More specifically it introduces:

- Implementation of more explicit Condition types to highlight
  abnormalities.
- Extensive usage of the `conditions` subpackage from `runtime`.
- Better and more conflict-resilient (status)patching of reconciled
  objects using the `patch` subpackage from runtime.
- Proper implementation of kstatus' `Reconciling` and `Stalled`
  conditions.
- Refactor of reconciler logic, including more efficient detection of
  changes to bucket objects by making use of the etag data available,
  and downloading of object files in parallel with a limited number of
  workers (4).
- Integration tests that solely rely on `testenv` and do not
  use Ginkgo.

There are a couple of TODOs marked in-code, these are suggestions for
the future and should be non-blocking.
In addition to the TODOs, more complex and/or edge-case test scenarios
may be added as well.

Signed-off-by: Hidde Beydals <hello@hidde.co>
This commit consolidates the `DownloadFailed` and `CheckoutFailed`
Condition types into a new more generic `FetchFailed` type to simplify
the API and observations by consumers.

Signed-off-by: Hidde Beydals <hello@hidde.co>
Add `BucketReconciler.reconcileArtifact` tests based on
`GitRepositoryReconciler.reconcileArtifact` test cases.

Signed-off-by: Sunny <darkowlzz@protonmail.com>
Signed-off-by: Sunny <darkowlzz@protonmail.com>
- Introduce mock GCP Server to test the gcp bucket client against mocked
  gcp server results.
- Add tests for reconcileGCPSource().
- Patch GCPClient.BucketExists() to return no error when the bucket
  doesn't exists. This keeps the GCP client compatible with the minio
  client.

Signed-off-by: Sunny <darkowlzz@protonmail.com>
hiddeco and others added 15 commits January 20, 2022 20:53
NOTE: Remove `hasArtifactUpdated` in the future once it's no longer
used.

Signed-off-by: Hidde Beydals <hello@hidde.co>
The problem with `GetInterval()` was that the returned type was of
`metav1.Duration`, while almost anywhere it was used, a type of
`time.Duration` was requested. The result of this was that we had to
call `GetInterval().Duration` all the time, which would become a bit
cumbersome after awhile.

To prevent this, we introduce a new `GetRequeueAfter() time.Duration`
method, which both results the right type, and bears a name that is
easier to remember where the value is used most; while setting the
`Result.RequeueAfter` during reconcile operations.

The introduction of this method deprecates `GetInterval()`, which
should be removed in a future MINOR release.

Signed-off-by: Sunny <darkowlzz@protonmail.com>

Co-authored-by: Hidde Beydals <hello@hidde.co>
Signed-off-by: Sunny <darkowlzz@protonmail.com>
Also, introduce FetchFailedCondition for generic fetch failures.

Signed-off-by: Sunny <darkowlzz@protonmail.com>

Co-authored-by: Hidde Beydals <hello@hidde.co>
Signed-off-by: Sunny <darkowlzz@protonmail.com>

Co-authored-by: Hidde Beydals <hello@hidde.co>
Embedding runtime.Object in Source interface makes the Source type more
useful to interact with k8s API machinery.

Signed-off-by: Sunny <darkowlzz@protonmail.com>
- internal/error - Contains internal error type used across the
  source-controller reconcilers.
- internal/reconcile - Contains helper abstractions for the
  controller-runtime reconcile Result type and functions to
  interact with the abstractions.

Signed-off-by: Sunny <darkowlzz@protonmail.com>
Signed-off-by: Sunny <darkowlzz@protonmail.com>
Signed-off-by: Sunny <darkowlzz@protonmail.com>
This commit rewrites the `BucketReconciler` to new standards, while
implementing the newly introduced Condition types, and trying to
adhere better to Kubernetes API conventions.

More specifically it introduces:

- Implementation of more explicit Condition types to highlight
  abnormalities.
- Extensive usage of the `conditions` subpackage from `runtime`.
- Better and more conflict-resilient (status)patching of reconciled
  objects using the `patch` subpackage from runtime.
- Proper implementation of kstatus' `Reconciling` and `Stalled`
  conditions.
- Refactor of reconciler logic, including more efficient detection of
  changes to bucket objects by making use of the etag data available,
  and downloading of object files in parallel with a limited number of
  workers (4).
- Integration tests that solely rely on `testenv` and do not
  use Ginkgo.

There are a couple of TODOs marked in-code, these are suggestions for
the future and should be non-blocking.
In addition to the TODOs, more complex and/or edge-case test scenarios
may be added as well.

Signed-off-by: Hidde Beydals <hello@hidde.co>
This commit consolidates the `DownloadFailed` and `CheckoutFailed`
Condition types into a new more generic `FetchFailed` type to simplify
the API and observations by consumers.

Signed-off-by: Hidde Beydals <hello@hidde.co>
Add `BucketReconciler.reconcileArtifact` tests based on
`GitRepositoryReconciler.reconcileArtifact` test cases.

Signed-off-by: Sunny <darkowlzz@protonmail.com>
Signed-off-by: Sunny <darkowlzz@protonmail.com>
- Introduce mock GCP Server to test the gcp bucket client against mocked
  gcp server results.
- Add tests for reconcileGCPSource().
- Patch GCPClient.BucketExists() to return no error when the bucket
  doesn't exists. This keeps the GCP client compatible with the minio
  client.

Signed-off-by: Sunny <darkowlzz@protonmail.com>
Ignore "not found" error while patching when the delete timestamp is
set.

Signed-off-by: Sunny <darkowlzz@protonmail.com>
- Remove ArtifactUnavailable condition and use Reconciling condition to
  convey the same.
- Make Reconciling condition affect the ready condition.
- Introduce summarizeAndPatch() to calculate the final status conditions
  and patch them.
- Introduce reconcile() to iterate through the sub-reconcilers and
  execute them.

Signed-off-by: Sunny <darkowlzz@protonmail.com>
Signed-off-by: Zhongcheng Lao <Zhongcheng.Lao@microsoft.com>
@darkowlzz darkowlzz force-pushed the reconcilers-dev-bucket branch 4 times, most recently from 55311a5 to 4b939ee Compare January 27, 2022 16:26
@laozc
Copy link
Contributor Author

laozc commented Feb 19, 2022

Ping.
We have some customers waiting for the support to land in flux.
Could you advise how to proceed?

@hiddeco
Copy link
Member

hiddeco commented Feb 21, 2022

We are working on getting the work of #586 in main. Once that's done, I will revise this PR (and #455), resolve the conflicts, and ensure it gets included in the same release as the one that introduces the v1beta2 API.

Sorry about the wait, changes in that PR are so broad that fitting additional things into it is a bit like playing Tetris 😅

@hiddeco hiddeco deleted the branch fluxcd:reconcilers-dev-bucket February 23, 2022 12:37
@hiddeco hiddeco closed this Feb 23, 2022
@hiddeco
Copy link
Member

hiddeco commented Feb 23, 2022

@laozc do not worry about the close. Feel either free to re-open a new one targeted against main, or wait for me to do it once I am done with #455.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants