@@ -1195,11 +1195,7 @@ func (c *HeadlampConfig) getClusters() []Cluster {
1195
1195
1196
1196
source := context .SourceStr ()
1197
1197
1198
- // find the file name from the kubeconfig path
1199
- fileName := filepath .Base (kubeconfigPath )
1200
-
1201
- // create the pathID string using a pipe as the delimiter
1202
- pathID := fmt .Sprintf ("%s:%s:%s" , context .SourceStr (), fileName , context .Name )
1198
+ pathID := context .PathID
1203
1199
1204
1200
clusters = append (clusters , Cluster {
1205
1201
Name : context .Name ,
@@ -1568,6 +1564,7 @@ func customNameToExtenstions(config *api.Config, contextName, newClusterName, pa
1568
1564
return nil
1569
1565
}
1570
1566
1567
+ // MOON - 9. MAKE THIS LOOK BY THE CONTEXT PATH ID
1571
1568
// updateCustomContextToCache updates the custom context to the cache.
1572
1569
func (c * HeadlampConfig ) updateCustomContextToCache (config * api.Config , clusterName string ) []error {
1573
1570
contexts , errs := kubeconfig .LoadContextsFromAPIConfig (config , false )
@@ -1581,6 +1578,7 @@ func (c *HeadlampConfig) updateCustomContextToCache(config *api.Config, clusterN
1581
1578
for _ , context := range contexts {
1582
1579
context := context
1583
1580
1581
+ // MOON - 7. MAKE THIS LOOK BY THE CONTEXT PATH ID
1584
1582
// Remove the old context from the store
1585
1583
if err := c .kubeConfigStore .RemoveContext (clusterName ); err != nil {
1586
1584
logger .Log (logger .LevelError , nil , err , "Removing context from the store" )
@@ -1603,31 +1601,35 @@ func (c *HeadlampConfig) updateCustomContextToCache(config *api.Config, clusterN
1603
1601
1604
1602
// getPathAndLoadKubeconfig gets the path of the kubeconfig file and loads it.
1605
1603
func (c * HeadlampConfig ) getPathAndLoadKubeconfig (source , clusterName string ) (string , * api.Config , error ) {
1606
- // Get path of kubeconfig from source
1607
- path , err := c .getKubeConfigPath (source )
1608
- if err != nil {
1609
- logger .Log (logger .LevelError , map [string ]string {"cluster" : clusterName },
1610
- err , "getting kubeconfig file" )
1611
-
1612
- return "" , nil , err
1613
- }
1614
1604
1615
1605
// Load kubeconfig file
1616
- config , err := clientcmd .LoadFromFile (path )
1606
+ config , err := clientcmd .LoadFromFile (source )
1617
1607
if err != nil {
1618
1608
logger .Log (logger .LevelError , map [string ]string {"cluster" : clusterName },
1619
1609
err , "loading kubeconfig file" )
1620
1610
1621
1611
return "" , nil , err
1622
1612
}
1623
1613
1624
- return path , config , nil
1614
+ return source , config , nil
1625
1615
}
1626
1616
1617
+ // MOON: - 1. ADD THE PATHID TO THE VARS SO WE CAN SORT BY PATH ID
1618
+
1627
1619
// Handler for renaming a cluster.
1628
1620
func (c * HeadlampConfig ) renameCluster (w http.ResponseWriter , r * http.Request ) {
1629
1621
vars := mux .Vars (r )
1630
1622
clusterName := vars ["name" ]
1623
+
1624
+ // takes the actual path to the kubeconfig file from the url pathID
1625
+ clusterPathID := r .URL .Query ().Get ("clusterPathID" )
1626
+
1627
+ pathID := clusterPathID
1628
+
1629
+ parts := strings .SplitN (pathID , ":" , 2 )
1630
+
1631
+ configPath := parts [0 ]
1632
+
1631
1633
// Parse request body.
1632
1634
var reqBody RenameClusterRequest
1633
1635
if err := json .NewDecoder (r .Body ).Decode (& reqBody ); err != nil {
@@ -1646,15 +1648,50 @@ func (c *HeadlampConfig) renameCluster(w http.ResponseWriter, r *http.Request) {
1646
1648
}
1647
1649
1648
1650
// Get path of kubeconfig from source
1649
- path , config , err := c .getPathAndLoadKubeconfig (reqBody . Source , clusterName )
1651
+ path , config , err := c .getPathAndLoadKubeconfig (configPath , clusterName )
1650
1652
if err != nil {
1651
1653
http .Error (w , "getting kubeconfig file" , http .StatusInternalServerError )
1652
1654
return
1653
1655
}
1654
1656
1657
+ // MOON - 2. WE WANT TO FIND THE CONTEXT WITH THE GIVEN PATHID AND NOT THE GIVEN NAME???
1655
1658
// Find the context with the given cluster name
1656
1659
contextName := clusterName
1657
1660
1661
+ // loop through every context in the kubeconfig and collect all the names
1662
+ // we do this because we want to be able to have the same name used for different config files
1663
+ var contextNames []string
1664
+
1665
+ for name := range config .Contexts {
1666
+ contextNames = append (contextNames , name )
1667
+
1668
+ logger .Log (logger .LevelInfo , map [string ]string {"cluster added" : name },
1669
+ nil , "context name" )
1670
+ }
1671
+
1672
+
1673
+
1674
+
1675
+ // Iterate over the contexts and add the custom names
1676
+ for _ , v := range config .Contexts {
1677
+ info := v .Extensions ["headlamp_info" ]
1678
+ if info != nil {
1679
+ customObj , err := MarshalCustomObject (info , contextName )
1680
+ if err != nil {
1681
+ logger .Log (logger .LevelError , map [string ]string {"cluster" : contextName },
1682
+ err , "marshaling custom object" )
1683
+
1684
+ return
1685
+ }
1686
+
1687
+ // Check if the CustomName field matches the cluster name
1688
+ if customObj .CustomName != "" {
1689
+ contextNames = append (contextNames , customObj .CustomName )
1690
+ }
1691
+ }
1692
+ }
1693
+
1694
+
1658
1695
// Iterate over the contexts to find the context with the given cluster name
1659
1696
for k , v := range config .Contexts {
1660
1697
info := v .Extensions ["headlamp_info" ]
@@ -1667,8 +1704,18 @@ func (c *HeadlampConfig) renameCluster(w http.ResponseWriter, r *http.Request) {
1667
1704
return
1668
1705
}
1669
1706
1707
+ // Check if the cluster name exists in the context names
1708
+ isUnique := checkUniqueName (contextNames , reqBody .NewClusterName )
1709
+ if (! isUnique ) {
1710
+ http .Error (w , "custom name already in use" , http .StatusBadRequest )
1711
+ logger .Log (logger .LevelError , map [string ]string {"cluster" : clusterName },
1712
+ err , "cluster name already exists in the kubeconfig" )
1713
+
1714
+ return
1715
+ }
1716
+
1670
1717
// Check if the CustomName field matches the cluster name
1671
- if customObj .CustomName != "" && customObj .CustomName == clusterName {
1718
+ if customObj .CustomName != "" && customObj .CustomName == clusterName && isUnique {
1672
1719
contextName = k
1673
1720
}
1674
1721
}
@@ -1679,6 +1726,7 @@ func (c *HeadlampConfig) renameCluster(w http.ResponseWriter, r *http.Request) {
1679
1726
return
1680
1727
}
1681
1728
1729
+ // MOON - 8. MAKE THIS LOOK BY THE CONTEXT PATH ID
1682
1730
if errs := c .updateCustomContextToCache (config , clusterName ); len (errs ) > 0 {
1683
1731
http .Error (w , "setting up contexts from kubeconfig" , http .StatusBadRequest )
1684
1732
return
@@ -1688,6 +1736,34 @@ func (c *HeadlampConfig) renameCluster(w http.ResponseWriter, r *http.Request) {
1688
1736
c .getConfig (w , r )
1689
1737
}
1690
1738
1739
+ // checkUniqueName returns false if 'newName' is already in 'names';
1740
+ // otherwise returns true.
1741
+ func checkUniqueName (names []string , newName string ) bool {
1742
+ for _ , current := range names {
1743
+ logger .Log (
1744
+ logger .LevelInfo ,
1745
+ map [string ]string {
1746
+ "message" : fmt .Sprintf ("now comparing %s to %s" , current , newName ),
1747
+ },
1748
+ nil ,
1749
+ "comparing cluster names" ,
1750
+ )
1751
+ if current == newName {
1752
+ logger .Log (
1753
+ logger .LevelInfo ,
1754
+ map [string ]string {
1755
+ "message" : fmt .Sprintf ("duplicate cluster name found: %s" , current ),
1756
+ },
1757
+ nil ,
1758
+ "cluster name already in use" ,
1759
+ )
1760
+ return false
1761
+ }
1762
+ }
1763
+ return true
1764
+ }
1765
+
1766
+
1691
1767
func (c * HeadlampConfig ) addClusterSetupRoute (r * mux.Router ) {
1692
1768
// Do not add the route if dynamic clusters are disabled
1693
1769
if ! c .enableDynamicClusters {
0 commit comments