Skip to content

Conversation

@tomasliumparas
Copy link

@tomasliumparas tomasliumparas commented Dec 5, 2024

Initial AccessConfig version.
To do:

  • Use domain from TunnelBinding
  • Discuss if we should create AccessApplications before DNS records due to security reasons
  • Implement AccessPolicies calls

Currently tested with the following CRD:

apiVersion: networking.cfargotunnel.com/v1alpha1
kind: TunnelBinding
metadata:
  name: whoami-cluster-tun
subjects:
  - name: whoami
  - name: whoami-2 # Points to the second service
tunnelRef:
  kind: ClusterTunnel
  name: k3s-cluster-tunnel
accessConfig:
  name: whoami
  domain: whoami.domain.com
  type: "self_hosted"

#67

@tomasliumparas tomasliumparas changed the title #67 Initial access config support Initial access config support Dec 5, 2024
Copy link
Owner

@adyanth adyanth left a comment

Choose a reason for hiding this comment

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

Thanks for the PR! Did you have a chance to test this out in your cluster to make sure it works? Had a couple questions/comments.

return ids, nil
}

func (c *CloudflareAPI) CreateAccessConfig(name string, config networkingv1alpha1.AccessConfig) error {
Copy link
Owner

Choose a reason for hiding this comment

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

Could you remove the dependency of networkingv1alpha1 from this file by calling this function with the newApp already created and accepting an AccessApp instead?

Copy link
Author

@tomasliumparas tomasliumparas Dec 6, 2024

Choose a reason for hiding this comment

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

The thing is that I need to call CF api, to have it translated into AccessApp - basically to translate Access Group Names into ids.
That means I would need to include CloudflareAPI from cloudflare_api.go into tunnelbinding_types.go

Or I could move (c *AccessConfig) NewAccessApplication() into controllers package as a function.
I did this, since I originally wanted to have it as a method of AccessConfig. That way it is near the definition of the CRD and it makes a bit easier to map the fields.

Which way you would prefer more?

Copy link
Owner

Choose a reason for hiding this comment

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

Feel free to include/import the CloudflareAPI in the tunnelbinding_types.go, or write a simple translation layer if we do not need all the fields. The cloudflare_api.go should not include any k8s CRDs to prevent circular deps.

c.Log.Error(err, "failed retrieving existing access policies for application", "applicationId", applicationId)
}

if len(existingPolicies) > 0 {
Copy link
Owner

Choose a reason for hiding this comment

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

This if condition is not necessary.

}

// Check if the policy is still required
required := false
Copy link
Owner

Choose a reason for hiding this comment

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

This function seems convoluted. Let me phrase what I understand this function should be doing and you can correct me.

Given the set of existing access policies on the application, and the set of access policies defined in the CRD, you are trying to reconcile them. But there are a couple of problems. Does having the same name of the policy guarantee that the policy wasn't changed? Do we also create access groups here or just refer to them by name?

If possible, I'd like to see this split up into smaller functions and sync all the rules regardless of what was present, unless there was a way you could verify what is set online matches the local config.

Copy link
Author

Choose a reason for hiding this comment

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

This one was a bit tricky.
What I am doing here is checking by name if there are any policies in the application, which are not defined in crd.
If yes, we delete them.

Later on we loop trough policies defined in crd and update them.

Cases I tested:

  • Policy by same name is changed manually, it should be updated to be matching crd configuration - works
  • Policy manually added to the ui, should be deleted - works
  • Policy should be deleted once gone from crd - works

Copy link
Author

Choose a reason for hiding this comment

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

does this makes sense?

Copy link
Owner

Choose a reason for hiding this comment

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

Policy manually added to the ui, should be deleted - works

This is approaching the terraform provider territory. All the operator needs to do is create what was defined in config, and clean it up when removed. If config is updated, create/update all of the configured ones. Looking for others might not be in the scope of this operator.

@tomasliumparas
Copy link
Author

Thanks for the PR! Did you have a chance to test this out in your cluster to make sure it works? Had a couple questions/comments.

Yes, seem to work fine.
What I managed to test:

  • Creation/deletion of Access Applications with/without the policies
  • Changing order of access policies
  • Manually updating the policies via Cloudflare
  • Removing the policies via CRD
  • Renaming the policies via CRD

@tomasliumparas
Copy link
Author

@adyanth can we resolve some of the comments?

@dvcrn
Copy link

dvcrn commented Jan 30, 2025

Thanks for taking the time of implementing this!

I tried testing this on my cluster but I couldn't get it to create access applications, is anything else missing?

apiVersion: networking.cfargotunnel.com/v1alpha1
kind: TunnelBinding
metadata:
  name: foo-bar
subjects:
  - name: svc-01
    spec:
      fqdn: foo-bar.mydomain.com
      protocol: http
tunnelRef:
  kind: ClusterTunnel
  name: my-tunnel
accessConfig:
  enabled: true
  type: "self_hosted"

I don't see any errors in the log. I also added access permission for applications to the token

@tomasliumparas
Copy link
Author

Thanks for taking the time of implementing this!

I tried testing this on my cluster but I couldn't get it to create access applications, is anything else missing?

apiVersion: networking.cfargotunnel.com/v1alpha1
kind: TunnelBinding
metadata:
  name: foo-bar
subjects:
  - name: svc-01
    spec:
      fqdn: foo-bar.mydomain.com
      protocol: http
tunnelRef:
  kind: ClusterTunnel
  name: my-tunnel
accessConfig:
  enabled: true
  type: "self_hosted"

I don't see any errors in the log. I also added access permission for applications to the token

Have you installed the updated CRDs inside your cluster? Could you provide operator log?

Copy link
Owner

@adyanth adyanth left a comment

Choose a reason for hiding this comment

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

Please rebase to latest main as well. Any further logic changes can be done iteratively once this is merged!

Comment on lines +122 to +138
type AccessConfig struct {
// Enable handling of access configuration
//+kubebuilder:validation:Optional
//+kubebuilder:default:=false
Enabled bool `json:"enabled"`
// Application type self_hosted,saas
//+kubebuilder:validation:Optional
//+kubebuilder:validation:Enum:="";"self_hosted";"saas"
//+kubebuilder:default:="self_hosted"
Type string `json:"type"`
// List of access policies
//+kubebuilder:validation:Optional
AccessPolicies []AccessPolicy `json:"accessPolicies"`
// Application settings
//+kubebuilder:validation:Optional
Settings AccessConfigSettings `json:"settings"`
}
Copy link
Owner

Choose a reason for hiding this comment

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

Since this is being used as part of the tunnelBinding, can we use only the configs that makes sense?

For example, the type would always need to be self_hosted, saas would never work. Do we need the enabled flag? If the config isn't specified, it is disabled.

Comment on lines +200 to +205
type AccessConfigAdditional struct {
// Cloudflare will render an SSH terminal or VNC session for this application in a web browser. [ssh,vnc]
//+kubebuilder:validation:Optional
//+kubebuilder:validation:Enum:="";"vnc";"ssh"
BrowserRendering string `json:"browserRendering"`
}
Copy link
Owner

Choose a reason for hiding this comment

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

This might need to be validated against the tunnelBinding subject's protocol, or rather use that to determine instead of being a config.

@tomasliumparas
Copy link
Author

Will come back to it soon

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.

3 participants