vitess.io/vitess@v0.16.2/go/vt/vtadmin/http/keyspaces.go (about)

     1  /*
     2  Copyright 2021 The Vitess Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package http
    18  
    19  import (
    20  	"context"
    21  	"encoding/json"
    22  	"strings"
    23  
    24  	"github.com/gorilla/mux"
    25  
    26  	"vitess.io/vitess/go/vt/vtadmin/errors"
    27  
    28  	vtadminpb "vitess.io/vitess/go/vt/proto/vtadmin"
    29  	vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata"
    30  )
    31  
    32  // CreateKeyspace implements the http wrapper for POST /keyspace/{cluster_id}.
    33  func CreateKeyspace(ctx context.Context, r Request, api *API) *JSONResponse {
    34  	vars := mux.Vars(r.Request)
    35  	decoder := json.NewDecoder(r.Body)
    36  	defer r.Body.Close()
    37  
    38  	var req vtctldatapb.CreateKeyspaceRequest
    39  	if err := decoder.Decode(&req); err != nil {
    40  		return NewJSONResponse(nil, &errors.BadRequest{
    41  			Err: err,
    42  		})
    43  	}
    44  
    45  	resp, err := api.server.CreateKeyspace(ctx, &vtadminpb.CreateKeyspaceRequest{
    46  		ClusterId: vars["cluster_id"],
    47  		Options:   &req,
    48  	})
    49  	return NewJSONResponse(resp, err)
    50  }
    51  
    52  // DeleteKeyspace implements the http wrapper for DELETE /keyspace/{cluster_id}/{name}[?recursive=].
    53  func DeleteKeyspace(ctx context.Context, r Request, api *API) *JSONResponse {
    54  	vars := mux.Vars(r.Request)
    55  	recursive, err := r.ParseQueryParamAsBool("recursive", false)
    56  	if err != nil {
    57  		return NewJSONResponse(nil, err)
    58  	}
    59  
    60  	resp, err := api.server.DeleteKeyspace(ctx, &vtadminpb.DeleteKeyspaceRequest{
    61  		ClusterId: vars["cluster_id"],
    62  		Options: &vtctldatapb.DeleteKeyspaceRequest{
    63  			Keyspace:  vars["name"],
    64  			Recursive: recursive,
    65  		},
    66  	})
    67  	return NewJSONResponse(resp, err)
    68  }
    69  
    70  // GetKeyspace implements the http wrapper for /keyspace/{cluster_id}/{name}.
    71  func GetKeyspace(ctx context.Context, r Request, api *API) *JSONResponse {
    72  	vars := mux.Vars(r.Request)
    73  	keyspace, err := api.server.GetKeyspace(ctx, &vtadminpb.GetKeyspaceRequest{
    74  		ClusterId: vars["cluster_id"],
    75  		Keyspace:  vars["name"],
    76  	})
    77  
    78  	return NewJSONResponse(keyspace, err)
    79  }
    80  
    81  // GetKeyspaces implements the http wrapper for /keyspaces[?cluster=[&cluster=]].
    82  func GetKeyspaces(ctx context.Context, r Request, api *API) *JSONResponse {
    83  	keyspaces, err := api.server.GetKeyspaces(ctx, &vtadminpb.GetKeyspacesRequest{
    84  		ClusterIds: r.URL.Query()["cluster"],
    85  	})
    86  
    87  	return NewJSONResponse(keyspaces, err)
    88  }
    89  
    90  // RebuildKeyspaceGraph implements the http wrapper for /keyspaces/{cluster_id}/{name}/rebuild_keyspace_graph
    91  func RebuildKeyspaceGraph(ctx context.Context, r Request, api *API) *JSONResponse {
    92  	vars := mux.Vars(r.Request)
    93  	decoder := json.NewDecoder(r.Body)
    94  	defer r.Body.Close()
    95  
    96  	var params struct {
    97  		Cells        string `json:"cells"`
    98  		AllowPartial bool   `json:"allow_partial"`
    99  	}
   100  
   101  	if err := decoder.Decode(&params); err != nil {
   102  		return NewJSONResponse(nil, &errors.BadRequest{
   103  			Err: err,
   104  		})
   105  	}
   106  
   107  	res, err := api.server.RebuildKeyspaceGraph(ctx, &vtadminpb.RebuildKeyspaceGraphRequest{
   108  		ClusterId:    vars["cluster_id"],
   109  		Keyspace:     vars["name"],
   110  		Cells:        strings.Split(params.Cells, ","),
   111  		AllowPartial: params.AllowPartial,
   112  	})
   113  
   114  	return NewJSONResponse(res, err)
   115  }
   116  
   117  // RemoveKeyspaceCell implements the http wrapper for /keyspaces/{cluster_id}/{name}/remove_keyspace_cell
   118  func RemoveKeyspaceCell(ctx context.Context, r Request, api *API) *JSONResponse {
   119  	vars := mux.Vars(r.Request)
   120  	decoder := json.NewDecoder(r.Body)
   121  	defer r.Body.Close()
   122  
   123  	var params struct {
   124  		Cell      string `json:"cell"`
   125  		Force     bool   `json:"force"`
   126  		Recursive bool   `json:"recursive"`
   127  	}
   128  
   129  	if err := decoder.Decode(&params); err != nil {
   130  		return NewJSONResponse(nil, &errors.BadRequest{
   131  			Err: err,
   132  		})
   133  	}
   134  
   135  	res, err := api.server.RemoveKeyspaceCell(ctx, &vtadminpb.RemoveKeyspaceCellRequest{
   136  		ClusterId: vars["cluster_id"],
   137  		Keyspace:  vars["name"],
   138  		Cell:      params.Cell,
   139  		Force:     params.Force,
   140  		Recursive: params.Recursive,
   141  	})
   142  
   143  	return NewJSONResponse(res, err)
   144  }
   145  
   146  // ValidateKeyspace validates that all nodes reachable from the specified keyspace are consistent.
   147  func ValidateKeyspace(ctx context.Context, r Request, api *API) *JSONResponse {
   148  	vars := mux.Vars(r.Request)
   149  	decoder := json.NewDecoder(r.Body)
   150  	defer r.Body.Close()
   151  
   152  	var result struct {
   153  		PingTablets bool `json:"pingTablets"`
   154  	}
   155  
   156  	if err := decoder.Decode(&result); err != nil {
   157  		return NewJSONResponse(nil, &errors.BadRequest{
   158  			Err: err,
   159  		})
   160  	}
   161  
   162  	res, err := api.server.ValidateKeyspace(ctx, &vtadminpb.ValidateKeyspaceRequest{
   163  		Keyspace:    vars["name"],
   164  		ClusterId:   vars["cluster_id"],
   165  		PingTablets: result.PingTablets,
   166  	})
   167  
   168  	return NewJSONResponse(res, err)
   169  }
   170  
   171  // ValidateKeyspace validates that all nodes reachable from the specified keyspace are consistent.
   172  func ValidateSchemaKeyspace(ctx context.Context, r Request, api *API) *JSONResponse {
   173  	vars := mux.Vars(r.Request)
   174  
   175  	res, err := api.server.ValidateSchemaKeyspace(ctx, &vtadminpb.ValidateSchemaKeyspaceRequest{
   176  		Keyspace:  vars["name"],
   177  		ClusterId: vars["cluster_id"],
   178  	})
   179  
   180  	return NewJSONResponse(res, err)
   181  }
   182  
   183  // ValidateVersionKeyspace validates that the version on the primary of shard 0 matches all of the other tablets in the keyspace.
   184  func ValidateVersionKeyspace(ctx context.Context, r Request, api *API) *JSONResponse {
   185  	vars := mux.Vars(r.Request)
   186  
   187  	res, err := api.server.ValidateVersionKeyspace(ctx, &vtadminpb.ValidateVersionKeyspaceRequest{
   188  		Keyspace:  vars["name"],
   189  		ClusterId: vars["cluster_id"],
   190  	})
   191  
   192  	return NewJSONResponse(res, err)
   193  }