Skip to content

Commit

Permalink
liqoctl: add create VirtualNode command
Browse files Browse the repository at this point in the history
  • Loading branch information
aleoli authored and adamjensenbot committed Aug 31, 2023
1 parent 5f72b45 commit f217d0f
Show file tree
Hide file tree
Showing 18 changed files with 732 additions and 5 deletions.
10 changes: 10 additions & 0 deletions cmd/liqoctl/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,19 @@ import (
"k8s.io/klog/v2"
"k8s.io/kubectl/pkg/cmd/util"

"github.com/liqotech/liqo/pkg/liqoctl/create"
"github.com/liqotech/liqo/pkg/liqoctl/delete"
"github.com/liqotech/liqo/pkg/liqoctl/factory"
"github.com/liqotech/liqo/pkg/liqoctl/rest"
"github.com/liqotech/liqo/pkg/liqoctl/rest/virtualnode"
)

var liqoctl string

var liqoResources = []rest.APIProvider{
virtualnode.VirtualNode,
}

func init() {
liqoctl = os.Args[0]

Expand Down Expand Up @@ -117,6 +125,8 @@ func NewRootCommand(ctx context.Context) *cobra.Command {
cmd.AddCommand(newMoveCommand(ctx, f))
cmd.AddCommand(newVersionCommand(ctx, f))
cmd.AddCommand(newDocsCommand(ctx))
cmd.AddCommand(create.NewCreateCommand(ctx, liqoResources, f))
cmd.AddCommand(delete.NewDeleteCommand(ctx, liqoResources, f))
return cmd
}

Expand Down
2 changes: 2 additions & 0 deletions cmd/liqoctl/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
netv1alpha1 "github.com/liqotech/liqo/apis/net/v1alpha1"
offloadingv1alpha1 "github.com/liqotech/liqo/apis/offloading/v1alpha1"
sharingv1alpha1 "github.com/liqotech/liqo/apis/sharing/v1alpha1"
virtualkubeletv1alpha1 "github.com/liqotech/liqo/apis/virtualkubelet/v1alpha1"
liqocmd "github.com/liqotech/liqo/cmd/liqoctl/cmd"
)

Expand All @@ -36,6 +37,7 @@ func init() {
utilruntime.Must(netv1alpha1.AddToScheme(scheme.Scheme))
utilruntime.Must(offloadingv1alpha1.AddToScheme(scheme.Scheme))
utilruntime.Must(sharingv1alpha1.AddToScheme(scheme.Scheme))
utilruntime.Must(virtualkubeletv1alpha1.AddToScheme(scheme.Scheme))
}

func main() {
Expand Down
2 changes: 1 addition & 1 deletion pkg/identityManager/certificate.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func (certManager *identityManager) StoreIdentity(ctx context.Context, remoteClu
Labels: map[string]string{
localIdentitySecretLabel: "true",
discovery.ClusterIDLabel: remoteCluster.ClusterID,
certificateAvailableLabel: "true",
CertificateAvailableLabel: "true",
},
Annotations: map[string]string{
// one year starting from now
Expand Down
7 changes: 4 additions & 3 deletions pkg/identityManager/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ package identitymanager
const defaultOrganization = "liqo.io"

const (
localIdentitySecretLabel = "discovery.liqo.io/local-identity"
remoteTenantCSRLabel = "discovery.liqo.io/remote-tenant-csr"
certificateAvailableLabel = "discovery.liqo.io/certificate-available"
localIdentitySecretLabel = "discovery.liqo.io/local-identity"
remoteTenantCSRLabel = "discovery.liqo.io/remote-tenant-csr"
// CertificateAvailableLabel is the label used to identify the secrets containing a certificate.
CertificateAvailableLabel = "discovery.liqo.io/certificate-available"
)

const (
Expand Down
2 changes: 1 addition & 1 deletion pkg/identityManager/identityManager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ var _ = Describe("IdentityManager", func() {
commonSecretChecks := func(secret *v1.Secret) {
Expect(secret.Namespace).To(Equal(namespace.Name))
Expect(secret.GetLabels()).To(HaveKeyWithValue(localIdentitySecretLabel, "true"))
Expect(secret.GetLabels()).To(HaveKeyWithValue(certificateAvailableLabel, "true"))
Expect(secret.GetLabels()).To(HaveKeyWithValue(CertificateAvailableLabel, "true"))
Expect(secret.GetLabels()).To(HaveKeyWithValue(discovery.ClusterIDLabel, remoteCluster.ClusterID))
Expect(secret.GetAnnotations()).To(HaveKey(certificateExpireTimeAnnotation))
Expect(secret.Data[privateKeySecretKey]).To(Equal(key))
Expand Down
78 changes: 78 additions & 0 deletions pkg/liqoctl/completion/completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import (

discoveryv1alpha1 "github.com/liqotech/liqo/apis/discovery/v1alpha1"
offloadingv1alpha1 "github.com/liqotech/liqo/apis/offloading/v1alpha1"
virtualkubeletv1alpha1 "github.com/liqotech/liqo/apis/virtualkubelet/v1alpha1"
identitymanager "github.com/liqotech/liqo/pkg/identityManager"
"github.com/liqotech/liqo/pkg/liqoctl/factory"
"github.com/liqotech/liqo/pkg/utils/slice"
)
Expand Down Expand Up @@ -123,6 +125,24 @@ func Nodes(ctx context.Context, f *factory.Factory, argsLimit int) FnType {
return common(ctx, f, argsLimit, retriever)
}

// VirtualNodes returns a function to autocomplete virtual node names.
func VirtualNodes(ctx context.Context, f *factory.Factory, argsLimit int) FnType {
retriever := func(ctx context.Context, f *factory.Factory) ([]string, error) {
var virtualNodes virtualkubeletv1alpha1.VirtualNodeList
if err := f.CRClient.List(ctx, &virtualNodes, client.InNamespace(f.Namespace)); err != nil {
return nil, err
}

var names []string
for i := range virtualNodes.Items {
names = append(names, virtualNodes.Items[i].Name)
}
return names, nil
}

return common(ctx, f, argsLimit, retriever)
}

// ForeignClusters returns a function to autocomplete ForeignCluster names.
func ForeignClusters(ctx context.Context, f *factory.Factory, argsLimit int) FnType {
retriever := func(ctx context.Context, f *factory.Factory) ([]string, error) {
Expand All @@ -141,6 +161,64 @@ func ForeignClusters(ctx context.Context, f *factory.Factory, argsLimit int) FnT
return common(ctx, f, argsLimit, retriever)
}

// ClusterIDs returns a function to autocomplete ForeignCluster cluster IDs.
func ClusterIDs(ctx context.Context, f *factory.Factory, argsLimit int) FnType {
retriever := func(ctx context.Context, f *factory.Factory) ([]string, error) {
var foreignClusters discoveryv1alpha1.ForeignClusterList
if err := f.CRClient.List(ctx, &foreignClusters); err != nil {
return nil, err
}

var ids []string
for i := range foreignClusters.Items {
ids = append(ids, foreignClusters.Items[i].Spec.ClusterIdentity.ClusterID)
}
return ids, nil
}

return common(ctx, f, argsLimit, retriever)
}

// ClusterNames returns a function to autocomplete ForeignCluster cluster names.
func ClusterNames(ctx context.Context, f *factory.Factory, argsLimit int) FnType {
retriever := func(ctx context.Context, f *factory.Factory) ([]string, error) {
var foreignClusters discoveryv1alpha1.ForeignClusterList
if err := f.CRClient.List(ctx, &foreignClusters); err != nil {
return nil, err
}

var names []string
for i := range foreignClusters.Items {
names = append(names, foreignClusters.Items[i].Spec.ClusterIdentity.ClusterName)
}
return names, nil
}

return common(ctx, f, argsLimit, retriever)
}

// KubeconfigSecretNames returns a function to autocomplete kubeconfig secret names.
func KubeconfigSecretNames(ctx context.Context, f *factory.Factory, argsLimit int) FnType {
retriever := func(ctx context.Context, f *factory.Factory) ([]string, error) {
matchingLabels := client.MatchingLabels{
identitymanager.CertificateAvailableLabel: "true",
}

var secrets corev1.SecretList
if err := f.CRClient.List(ctx, &secrets, client.InNamespace(f.Namespace), matchingLabels); err != nil {
return nil, err
}

var names []string
for i := range secrets.Items {
names = append(names, secrets.Items[i].Name)
}
return names, nil
}

return common(ctx, f, argsLimit, retriever)
}

// PVCs returns a function to autocomplete PVC names.
func PVCs(ctx context.Context, f *factory.Factory, argsLimit int) FnType {
retriever := func(ctx context.Context, f *factory.Factory) ([]string, error) {
Expand Down
16 changes: 16 additions & 0 deletions pkg/liqoctl/create/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright 2019-2023 The Liqo 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 create contains the implementation of the 'create' command
package create
51 changes: 51 additions & 0 deletions pkg/liqoctl/create/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright 2019-2023 The Liqo 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 create

import (
"context"

"github.com/spf13/cobra"

"github.com/liqotech/liqo/pkg/liqoctl/factory"
"github.com/liqotech/liqo/pkg/liqoctl/rest"
)

// NewCreateCommand returns the cobra command for the create subcommand.
func NewCreateCommand(ctx context.Context, liqoResources []rest.APIProvider, f *factory.Factory) *cobra.Command {
options := &rest.CreateOptions{
Factory: f,
}

cmd := &cobra.Command{
Use: "create",
Short: "Create Liqo resources",
Long: "Create Liqo resources.",
Args: cobra.NoArgs,
}

f.AddNamespaceFlag(cmd.PersistentFlags())

for _, r := range liqoResources {
api := r()

apiOptions := api.APIOptions()
if apiOptions.EnableCreate {
cmd.AddCommand(api.Create(ctx, options))
}
}

return cmd
}
16 changes: 16 additions & 0 deletions pkg/liqoctl/delete/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright 2019-2023 The Liqo 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 delete contains the implementation of the 'delete' command
package delete
51 changes: 51 additions & 0 deletions pkg/liqoctl/delete/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright 2019-2023 The Liqo 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 delete

import (
"context"

"github.com/spf13/cobra"

"github.com/liqotech/liqo/pkg/liqoctl/factory"
"github.com/liqotech/liqo/pkg/liqoctl/rest"
)

// NewDeleteCommand returns the cobra command for the delete subcommand.
func NewDeleteCommand(ctx context.Context, liqoResources []rest.APIProvider, f *factory.Factory) *cobra.Command {
options := &rest.DeleteOptions{
Factory: f,
}

cmd := &cobra.Command{
Use: "delete",
Short: "Delete Liqo resources",
Long: "Delete Liqo resources.",
Args: cobra.NoArgs,
}

f.AddNamespaceFlag(cmd.PersistentFlags())

for _, r := range liqoResources {
api := r()

apiOptions := api.APIOptions()
if apiOptions.EnableDelete {
cmd.AddCommand(api.Delete(ctx, options))
}
}

return cmd
}
16 changes: 16 additions & 0 deletions pkg/liqoctl/rest/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright 2019-2023 The Liqo 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 rest contains the types and interfaces to interact with the Liqo API.
package rest
68 changes: 68 additions & 0 deletions pkg/liqoctl/rest/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright 2019-2023 The Liqo 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 rest

import (
"context"

"github.com/spf13/cobra"

"github.com/liqotech/liqo/pkg/liqoctl/factory"
)

// APIOptions contains the options for the API.
type APIOptions struct {
EnableCreate bool
EnableDelete bool
EnableGet bool
EnableUpdate bool
}

// CreateOptions contains the options for the create API.
type CreateOptions struct {
*factory.Factory

OutputFormat string
Name string
}

// DeleteOptions contains the options for the delete API.
type DeleteOptions struct {
*factory.Factory

Name string
}

// GetOptions contains the options for the get API.
type GetOptions struct {
*factory.Factory
}

// UpdateOptions contains the options for the update API.
type UpdateOptions struct {
*factory.Factory
}

// API is the interface that must be implemented by the API.
type API interface {
APIOptions() *APIOptions
Create(ctx context.Context, options *CreateOptions) *cobra.Command
Delete(ctx context.Context, options *DeleteOptions) *cobra.Command
Get(ctx context.Context, options *GetOptions) *cobra.Command
Update(ctx context.Context, options *UpdateOptions) *cobra.Command
}

// APIProvider is the function that returns the API.
type APIProvider func() API
Loading

0 comments on commit f217d0f

Please sign in to comment.