Skip to content

Commit

Permalink
improve docs and simplify const usage
Browse files Browse the repository at this point in the history
  • Loading branch information
marcoandredinis committed Jun 28, 2022
1 parent 922e7bc commit fd91982
Show file tree
Hide file tree
Showing 11 changed files with 88 additions and 49 deletions.
22 changes: 10 additions & 12 deletions lib/kube/proxy/forwarder.go
Original file line number Diff line number Diff line change
Expand Up @@ -1527,12 +1527,11 @@ func (f *Forwarder) catchAll(ctx *authContext, w http.ResponseWriter, req *http.

func (f *Forwarder) getExecutor(ctx authContext, sess *clusterSession, req *http.Request) (remotecommand.Executor, error) {
upgradeRoundTripper := NewSpdyRoundTripperWithDialer(roundTripperConfig{
ctx: req.Context(),
authCtx: ctx,
dial: sess.DialWithContext,
tlsConfig: sess.tlsConfig,
followRedirects: true,
pingPeriod: f.cfg.ConnPingPeriod,
ctx: req.Context(),
authCtx: ctx,
dial: sess.DialWithContext,
tlsConfig: sess.tlsConfig,
pingPeriod: f.cfg.ConnPingPeriod,
})
rt := http.RoundTripper(upgradeRoundTripper)
if sess.creds != nil {
Expand All @@ -1547,12 +1546,11 @@ func (f *Forwarder) getExecutor(ctx authContext, sess *clusterSession, req *http

func (f *Forwarder) getDialer(ctx authContext, sess *clusterSession, req *http.Request) (httpstream.Dialer, error) {
upgradeRoundTripper := NewSpdyRoundTripperWithDialer(roundTripperConfig{
ctx: req.Context(),
authCtx: ctx,
dial: sess.DialWithContext,
tlsConfig: sess.tlsConfig,
followRedirects: true,
pingPeriod: f.cfg.ConnPingPeriod,
ctx: req.Context(),
authCtx: ctx,
dial: sess.DialWithContext,
tlsConfig: sess.tlsConfig,
pingPeriod: f.cfg.ConnPingPeriod,
})
rt := http.RoundTripper(upgradeRoundTripper)
if sess.creds != nil {
Expand Down
11 changes: 5 additions & 6 deletions lib/kube/proxy/roundtrip.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,11 @@ var _ utilnet.Dialer = &SpdyRoundTripper{}
type DialWithContext func(context context.Context, network, address string) (net.Conn, error)

type roundTripperConfig struct {
ctx context.Context
authCtx authContext
dial DialWithContext
tlsConfig *tls.Config
followRedirects bool
pingPeriod time.Duration
ctx context.Context
authCtx authContext
dial DialWithContext
tlsConfig *tls.Config
pingPeriod time.Duration
}

// NewSpdyRoundTripperWithDialer creates a new SpdyRoundTripper that will use
Expand Down
13 changes: 6 additions & 7 deletions operator/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ The first two steps above may change the object's state in K8S. If they do, we u
### Requirementes

#### K8S cluster
You can use `minikube` if you don't have a cluster yet.
If you don't have a cluster yet, you can start one by using the [minikube](https://minikube.sigs.k8s.io/docs/start/) tool.

#### Operator's docker image
You can obtain the docker image by pulling from `quay.io/gravitational/teleport`
Expand All @@ -93,8 +93,6 @@ We also need the following tools: `helm`, `kubectl` and `docker`

### Running the operator

Start `minikube` with `minikube start`.

Set the `TELEPORT_PROJECT` to the full path to your teleport's project checked out at `marco/plugins-teleport-operator-charts`.

Install the helm chart:
Expand All @@ -118,9 +116,9 @@ If it doesn't, check the errors.

Now, we want access to two configuration tools using a Web UI: K8S UI and Teleport UI.

First, let's create a tunnel using minikube: `minikube tunnel` (this command runs is foreground, open another terminal for the remaining commands).
If you are using `minikube`, you have to create a tunnel with: `minikube tunnel` (this command runs is foreground, open another terminal for the remaining commands).

Now, let's create a new Teleport User and login in the web UI:
Create a new Teleport User and login in the web UI:
```bash
PROXY_POD=$(kubectl get po -l app=teleport-cluster -o jsonpath='{.items[0].metadata.name}')
kubectl exec $PROXY_POD teleport -- tctl users add --roles=access,editor teleoperator
Expand All @@ -129,9 +127,10 @@ TP_CLUSTER_IP=$(kubectl get service teleport-cluster -o jsonpath='{ .status.load
echo "https://${TP_CLUSTER_IP}/web/invite/<id>"
```

As for the K8S UI, you only need to run `minikube dashboard`.
Open the Kubernetes Dashboard (`minikube dashboard` if your cluster was created by `minikube`) and switch to `teleport-cluster` namespace.
Your resources will appear under the Custom Resources menu.

After this, you should be able to manage users and roles using, for example, `kubectl`.
You can manage users and roles using to usual kubernetes tools, for example, `kubectl`.

As an example, create the following file (`roles.yaml`) and then apply it:
```yaml
Expand Down
22 changes: 22 additions & 0 deletions operator/apis/resources/constants.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
Copyright 2022 Gravitational, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 resources

const (
GroupName = "resources.teleport.dev"
DescriptionKey = "description"
)
4 changes: 3 additions & 1 deletion operator/apis/resources/v2/groupversion_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ package v2
import (
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/controller-runtime/pkg/scheme"

"github.com/gravitational/teleport/operator/apis/resources"
)

var (
// GroupVersion is group version used to register these objects
GroupVersion = schema.GroupVersion{Group: "resources.teleport.dev", Version: "v2"}
GroupVersion = schema.GroupVersion{Group: resources.GroupName, Version: "v2"}

// SchemeBuilder is used to add go types to the GroupVersionKind scheme
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
Expand Down
11 changes: 5 additions & 6 deletions operator/apis/resources/v2/user_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,12 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/operator/apis/resources"
)

const DescriptionKey = "description"
func init() {
SchemeBuilder.Register(&User{}, &UserList{})
}

// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
Expand Down Expand Up @@ -57,18 +60,14 @@ type UserList struct {
Items []User `json:"items"`
}

func init() {
SchemeBuilder.Register(&User{}, &UserList{})
}

func (u User) ToTeleport() types.User {
return &types.UserV2{
Kind: types.KindUser,
Version: types.V2,
Metadata: types.Metadata{
Name: u.Name,
Labels: u.Labels,
Description: u.Annotations[DescriptionKey],
Description: u.Annotations[resources.DescriptionKey],
},
Spec: types.UserSpecV2(u.Spec),
}
Expand Down
4 changes: 3 additions & 1 deletion operator/apis/resources/v5/groupversion_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ package v5
import (
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/controller-runtime/pkg/scheme"

"github.com/gravitational/teleport/operator/apis/resources"
)

var (
// GroupVersion is group version used to register these objects
GroupVersion = schema.GroupVersion{Group: "resources.teleport.dev", Version: "v5"}
GroupVersion = schema.GroupVersion{Group: resources.GroupName, Version: "v5"}

// SchemeBuilder is used to add go types to the GroupVersionKind scheme
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
Expand Down
11 changes: 5 additions & 6 deletions operator/apis/resources/v5/role_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,12 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/operator/apis/resources"
)

const DescriptionKey = "description"
func init() {
SchemeBuilder.Register(&Role{}, &RoleList{})
}

// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
Expand Down Expand Up @@ -57,18 +60,14 @@ type RoleList struct {
Items []Role `json:"items"`
}

func init() {
SchemeBuilder.Register(&Role{}, &RoleList{})
}

func (r Role) ToTeleport() types.Role {
return &types.RoleV5{
Kind: types.KindRole,
Version: types.V5,
Metadata: types.Metadata{
Name: r.Name,
Labels: r.Labels,
Description: r.Annotations[DescriptionKey],
Description: r.Annotations[resources.DescriptionKey],
},
Spec: types.RoleSpecV5(r.Spec),
}
Expand Down
35 changes: 27 additions & 8 deletions operator/controllers/resources/reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,30 @@ type ResourceBaseReconciler struct {
UpsertExternal UpsertExternal
}

/*
Do will receive an update request and reconcile the resource.
When an event arrives we must propagate that change into the Teleport cluster.
We have two types of events: update/create and delete.
For creating/updating we check if the resource exists in Teleport
- if it does, we update it
- otherwise we create it
Always using the state of the resource in the cluster as the source of truth.
For deleting, the recommendation is to use finalizers.
Finalizers allow us to map an external resource to a kubernetes resource.
So, when we create or update a resource, we add our own finalizer to the kubernetes resource list of finalizers.
For a delete event which has our finalizer: the resource is deleted in Teleport.
If it doesn't have the finalizer, we do nothing.
----
Every time we update a resource in Kubernetes (adding finalizers or the OriginLabel), we end the reconciliation process.
Afterwards, we receive the request again and we progress to the next step.
This allow us to progress with smaller changes and avoid a long-running reconciliation.
*/
func (r ResourceBaseReconciler) Do(ctx context.Context, req ctrl.Request, obj kclient.Object) (ctrl.Result, error) {
// https://sdk.operatorframework.io/docs/building-operators/golang/advanced-topics/#external-resources
log := log.FromContext(ctx).WithValues("namespacedname", req.NamespacedName)
Expand Down Expand Up @@ -101,16 +125,11 @@ func hasOriginLabel(obj kclient.Object) bool {
return false
}

for k := range obj.GetLabels() {
if k == types.OriginLabel {
return true
}
}

return false
_, ok := obj.GetLabels()[types.OriginLabel]
return ok
}

func addOriginLabel(ctx context.Context, k8sClient kclient.Client, obj kclient.Object) error {
func addOriginLabelToK8SObject(ctx context.Context, k8sClient kclient.Client, obj kclient.Object) error {
k8sObjLabels := obj.GetLabels()
if k8sObjLabels == nil {
k8sObjLabels = make(map[string]string)
Expand Down
2 changes: 1 addition & 1 deletion operator/controllers/resources/role_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func (r *RoleReconciler) Upsert(ctx context.Context, obj kclient.Object) error {
return trace.Wrap(err)
}
if trace.IsNotFound(err) && !hasOriginLabel(obj) {
return addOriginLabel(ctx, r.Client, obj)
return addOriginLabelToK8SObject(ctx, r.Client, obj)
}

return r.TeleportClient.UpsertRole(ctx, teleportResource)
Expand Down
2 changes: 1 addition & 1 deletion operator/controllers/resources/user_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func (r *UserReconciler) Upsert(ctx context.Context, obj kclient.Object) error {
}
if trace.IsNotFound(err) {
if !hasOriginLabel(obj) {
return addOriginLabel(ctx, r.Client, obj)
return addOriginLabelToK8SObject(ctx, r.Client, obj)
}

return trace.Wrap(r.TeleportClient.CreateUser(ctx, teleportResource))
Expand Down

0 comments on commit fd91982

Please sign in to comment.